I use a sample to play gifs in my app,
but start(), stop() and pause() methods not working.
sample: enter link description here
nuget package: Install-Package Karamunting.Android.Koral.AndroidGifDrawable
This is my code
enter image description here
Thanks for helping me...
🎊 Welcome to SO 🎊
That exception thrown because you casts wrong object to wrong Type (GifDrawable).
To achieve what you want, you have to get Drawable object first by accessing GifImageView.Drawable property and then cast it to GifDrawable.
Now you can access those methods (.Stop(), .Start()) correctly.
Sample code:
var gifImageView0 = FindViewById<GifImageView>(Resource.Id.gif6);
var stop = FindViewById<Button>(Resource.Id.button1);
stop.Click += (s, e) =>
{
//
(gifImageView0.Drawable as GifDrawable)?.Stop();
};
Welcome to SO!
I have checked the Karamunting.Android.Koral.AndroidGifDrawable Nuget Package, it seems not providing the guides for Xamarin Android to invoke it. And there is only 721 downloads. After testing in my local site, it has many errors when using its methods shared from GitHub. I think it will need more time to solve problems about specified cast is not valid.
Therefore, I will suggest that installing Refractored.GifImageView from JamesMontemagno. I have test that in local site, and it wroks so conveniently.And you can refer to its GitHub to know how to use in Xamarin Android.
Install it:
Sample code as follows:
public class MainActivity : AppCompatActivity
{
Felipecsl.GifImageViewLibrary.GifImageView gifImageView;
//PL.DroidsOnRoids.Gif.GifImageView gifImageViewTrans;
Button btnToggle;
Button btnStart;
Button btnStop;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
gifImageView = FindViewById<Felipecsl.GifImageViewLibrary.GifImageView>(Resource.Id.gifImageView);
//gifImageViewTrans = FindViewById<PL.DroidsOnRoids.Gif.GifImageView>(Resource.Id.gifImageView2);
btnToggle = FindViewById<Button>(Resource.Id.btnToggle);
btnStart = FindViewById<Button>(Resource.Id.btnStart);
btnStop = FindViewById<Button>(Resource.Id.btnStop);
// From Drawable
Stream input = Resources.OpenRawResource(Resource.Drawable.timg);
// You should convert the "input" into Byte Array
byte[] bytes = ConvertByteArray(input);
gifImageView.SetBytes(bytes);
gifImageView.StartAnimation();
btnToggle.Click += (sender, e) =>
{
try
{
if (gifImageView.IsAnimating)
gifImageView.StopAnimation();
else
gifImageView.StartAnimation();
}
catch (Exception ex)
{
}
};
btnStart.Click += BtnStart_Click;
btnStop.Click += BtnStop_Click;
}
private void BtnStop_Click(object sender, EventArgs e)
{
gifImageView.StopAnimation();
}
private void BtnStart_Click(object sender, EventArgs e)
{
gifImageView.StartAnimation();
}
private byte[] ConvertByteArray(Stream input)
{
byte[] buffer = new byte[16 * 1024];
using (MemoryStream ms = new MemoryStream())
{
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
ms.Write(buffer, 0, read);
return ms.ToArray();
}
}
}
The effect:
Related
I have a Xamarin.Forms application that supports only UWP. I cannot find a way to print a pdf document. Whatever I have seen on the web, for some reason doesn't work for me. E.g. I tried
https://www.syncfusion.com/kb/8767/how-to-print-pdf-documents-in-xamarin-forms-platform
It lets me print, but the preview in the print dialog never shows up, and the progress indicator just keeps rotating forever.
I also tried http://zawayasoft.com/2018/03/13/uwp-print-pdf-files-silently-without-print-dialog/
This gives me errors that I cannot fix.
So I wonder if somebody can suggest something else that would actually work. Maybe something newer than what I have tried (I use VS 2017). Printing without the printing dialog would be preferable.
Thank you in advance.
I used a very dirty hack to do that!
What I had to do was to try to print the image version of the pdf (I did the conversion in backend) and then used the following DependencyInjection:
Inside my Print class in UWP project:
class Print : IPrint
{
void IPrint.Print(byte[] content)
{
Print_UWP printing = new Print_UWP();
printing.PrintUWpAsync(content);
}
}
and the class responsible for printing in uwp:
public class Print_UWP
{
PrintManager printmgr = PrintManager.GetForCurrentView();
PrintDocument PrintDoc = null;
PrintDocument printDoc;
PrintTask Task = null;
Windows.UI.Xaml.Controls.Image ViewToPrint = new Windows.UI.Xaml.Controls.Image();
public Print_UWP()
{
printmgr.PrintTaskRequested += Printmgr_PrintTaskRequested;
}
public async void PrintUWpAsync(byte[] imageData)
{
int i = 0;
while (i < 5)
{
try
{
BitmapImage biSource = new BitmapImage();
using (InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream())
{
await stream.WriteAsync(imageData.AsBuffer());
stream.Seek(0);
await biSource.SetSourceAsync(stream);
}
ViewToPrint.Source = biSource;
if (PrintDoc != null)
{
printDoc.GetPreviewPage -= PrintDoc_GetPreviewPage;
printDoc.Paginate -= PrintDoc_Paginate;
printDoc.AddPages -= PrintDoc_AddPages;
}
this.printDoc = new PrintDocument();
try
{
printDoc.GetPreviewPage += PrintDoc_GetPreviewPage;
printDoc.Paginate += PrintDoc_Paginate;
printDoc.AddPages += PrintDoc_AddPages;
bool showprint = await PrintManager.ShowPrintUIAsync();
}
catch (Exception e)
{
Debug.WriteLine(e.ToString());
}
// printmgr = null;
// printDoc = null;
// Task = null;
PrintDoc = null;
GC.Collect();
printmgr.PrintTaskRequested -= Printmgr_PrintTaskRequested;
break;
}
catch (Exception e)
{
i++;
}
}
}
private void Printmgr_PrintTaskRequested(PrintManager sender, PrintTaskRequestedEventArgs args)
{
var deff = args.Request.GetDeferral();
Task = args.Request.CreatePrintTask("Invoice", OnPrintTaskSourceRequested);
deff.Complete();
}
async void OnPrintTaskSourceRequested(PrintTaskSourceRequestedArgs args)
{
var def = args.GetDeferral();
await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
args.SetSource(printDoc.DocumentSource);
});
def.Complete();
}
private void PrintDoc_AddPages(object sender, AddPagesEventArgs e)
{
printDoc.AddPage(ViewToPrint);
printDoc.AddPagesComplete();
}
private void PrintDoc_Paginate(object sender, PaginateEventArgs e)
{
PrintTaskOptions opt = Task.Options;
printDoc.SetPreviewPageCount(1, PreviewPageCountType.Final);
}
private void PrintDoc_GetPreviewPage(object sender, GetPreviewPageEventArgs e)
{
printDoc.SetPreviewPage(e.PageNumber, ViewToPrint);
}
}
Please note that this is not a perfect solution and sometimes it crashes without actually being able to trace the exception (which is really strange) so I am sure there must be better answers even though it does the job.
I am implementing a camera function directly in an app, as I do not want to use Intent to open the default camera application. I have followed the code provided here:
The app crashes as soon as the photo gets taken, with the following error message:
Java.Lang.RuntimeException: Fail to connect to camera service
Here is how I set it up. I have ommited the unneccessary code.
namespace camera_test
{
[Activity(Label = "#string/app_name", Theme = "#style/AppTheme", MainLauncher = true, Icon = "#drawable/icon")]
public class MainActivity : Android.Support.V7.App.AppCompatActivity, Android.Hardware.Camera.IPictureCallback, Android.Hardware.Camera.IPreviewCallback,
Android.Hardware.Camera.IShutterCallback, ISurfaceHolderCallback
{
static Android.Hardware.Camera camera = null;
Button btnStart;
Button btnEnd;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
SurfaceView surface = (SurfaceView)FindViewById(Resource.Id.surface);
var holder = surface.Holder;
holder.AddCallback(this);
holder.SetType(Android.Views.SurfaceType.PushBuffers);
btnStart = FindViewById<Button>(Resource.Id.buttonStart);
btnEnd = FindViewById<Button>(Resource.Id.buttonEnd);
btnStart.Click += BtnStart_Click;
btnEnd.Click += BtnEnd_Click;
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder(); StrictMode.SetVmPolicy(builder.Build());
}
private void BtnStart_Click(object sender, EventArgs e)
{
camera.StartPreview();
private void BtnEnd_Click(object sender, EventArgs e)
{
Android.Hardware.Camera.Parameters p = camera.GetParameters();
p.PictureFormat = Android.Graphics.ImageFormatType.Jpeg;
camera.SetParameters(p);
camera.TakePicture(this, this, this);
StartActivity(typeof(MainActivity));
}
void Android.Hardware.Camera.IPictureCallback.OnPictureTaken(byte[] data, Android.Hardware.Camera camera)
{
Java.IO.FileOutputStream outStream = null;
Java.IO.File dataDir = Android.OS.Environment.ExternalStorageDirectory;
DateTime DT = DateTime.Now;
String DateTimeStamp = DT.Year.ToString("D4") + "-" + DT.Month.ToString("D2") + "-" + DT.Day.ToString("D2") + "-" + DT.Hour.ToString("D2") + DT.Minute.ToString("D2") + DT.Second.ToString("D2");
String PictureFilename = "Photo-" + DateTimeStamp + ".jpg";
if (data != null)
{
try
{
outStream = new Java.IO.FileOutputStream(dataDir + "/" + PictureFilename);
outStream.Write(data);
outStream.Close();
}
catch (FileNotFoundException e)
{
System.Console.Out.WriteLine(e.Message);
}
catch (IOException ie)
{
System.Console.Out.WriteLine(ie.Message);
}
}
}
void Android.Hardware.Camera.IPreviewCallback.OnPreviewFrame(byte[] b, Android.Hardware.Camera c)
{
}
void Android.Hardware.Camera.IShutterCallback.OnShutter()
{
}
public void SurfaceCreated(ISurfaceHolder holder)
{
try
{
camera = Android.Hardware.Camera.Open();
Android.Hardware.Camera.Parameters p = camera.GetParameters();
p.PictureFormat = Android.Graphics.ImageFormatType.Jpeg;
camera.SetParameters(p);
camera.SetPreviewCallback(this);
camera.Lock();
camera.SetPreviewDisplay(holder);
// camera.StartPreview();
}
catch (IOException e)
{
}
}
public void SurfaceDestroyed(ISurfaceHolder holder)
{
camera.Unlock();
camera.StopPreview();
camera.SetPreviewCallback(null);
camera.Release();
camera = null;
}
public void SurfaceChanged(ISurfaceHolder holder, Android.Graphics.Format f, int i, int j)
{
}
}
}
I am guessing it has something to do with the way in which the camera is opened and closed, but I can't figure out how to solve this problem. Note that the start button correctly starts the camera viewer. It is only when the end button is clicked does the app crash. Any help or suggestions would be appreciated. Also, I know that camera has been depreciated. Thanks.
UPDATE:
The error occurs when:
the device changes orientation
or when I call this line: StartActivity(typeof(MainActivity));.
I.e, the error occurs when the acitvity gets restarted (I think that if the orientation changes then it restarts the activity as well). I have no idea how else to restart my activity because I need to. Interestingly, if I switch to a different activity then switch back to my main activity that has the camera function, the error does not occure. I am very puzzled.
Is there a reason why you use the deprecated camera api?
You should use camera2:
https://developer.android.com/reference/android/hardware/camera2/package-summary
Xamarin also provides a basic example for this:
https://developer.xamarin.com/samples/monodroid/android5.0/Camera2Basic/
In my application, when a user clicks on a menu item, they are prompted to select a file which I then use a background worker to load and parse with progress being reported to a progress bar during this operation. when the work is complete, I start a new window which i pass the parsed data to. for some reason, the new window is getting opened before the data is parsed and null arguments are passed instead of the data.
my Click Event:
private void CIRCUIT_INSTALATION_SCHEDULED_Click(object sender, RoutedEventArgs e)
{
//prevents users from selecting other menu items
disableAll();
System.Windows.Forms.OpenFileDialog mainExcelFileDialog = new System.Windows.Forms.OpenFileDialog();
mainExcelFileDialog.InitialDirectory = System.Configuration.ConfigurationManager.AppSettings["MainWorkbookDirectory"];
mainExcelFileDialog.Title = "Main Excel File";
mainExcelFileDialog.ShowDialog();
string mainPath = mainExcelFileDialog.FileName;
this.Cursor = System.Windows.Input.Cursors.Wait;
BackgroundWorker cisWorker = new BackgroundWorker();
cisWorker.DoWork += cisWorker_DoWork;
cisWorker.ProgressChanged+=cisWorker_ProgressChanged;
cisWorker.RunWorkerCompleted += cisWorker_RunWorkerCompleted;
cisWorker.RunWorkerAsync(mainPath);
}
my Do Work:
void cisWorker_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
using (FileStream fs = new FileStream(e.Argument.ToString() , FileMode.Open))
{
//copy filestream to memorystream chunk by chunk, reporting progress.
using (MemoryStream ms = new MemoryStream())
{
byte[] buffer = new byte[32768];
int read;
int steps = Convert.ToInt32(fs.Length / buffer.Length);
int i = 0;
while ((read = fs.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
i++;
var progress = new Decimal(i) / new Decimal(steps);
var outOf = Math.Round(progress * 50);
worker.ReportProgress(Convert.ToInt32(outOf));
}
worker.ReportProgress(50);
ms.Position = 0;
//load excel workbook dataset from memorystream
using (var xlr = Excel.ExcelReaderFactory.CreateOpenXmlReader(ms))
{
xlr.IsFirstRowAsColumnNames = true;
mainWorkbook = xlr.AsDataSet();
worker.ReportProgress(100);
}
}
}
}
my on complete:
void cisWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.Cursor = System.Windows.Input.Cursors.Arrow;
CircuitInstallationScheduledWindow CIS_Window = new CircuitInstallationScheduledWindow();
CIS_Window.Show();
CIS_Window.Closed += CIS_Window_Closed;
}
EDIT:
I added the mainPath argument to the cisWorker.runWorkerAsync() method. the problem persists unfortunately.
Basically you should check for your data not being null, i.e that no error occurred during DoWork
void cisWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error == null)
{
/* Your mainWorkbook shouldn't be null */
this.Cursor = System.Windows.Input.Cursors.Arrow;
CircuitInstallationScheduledWindow CIS_Window = new CircuitInstallationScheduledWindow();
CIS_Window.Show();
CIS_Window.Closed += CIS_Window_Closed;
}
else
{
// Handle error
}
}
Henk Holterman was right. I was getting an error because I had not set cisWorker.WorkerReportsProgress = true; I still don't know why the error wasn't breaking the debugger since it wasn't being handled, but I did a print statement in my Completed method which helped me track down the culprit.
void cisWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
Console.WriteLine(e.Error);
this.Cursor = System.Windows.Input.Cursors.Arrow;
CircuitInstallationScheduledWindow CIS_Window = new CircuitInstallationScheduledWindow(mainWorkbook, abfsDatabase);
CIS_Window.Show();
CIS_Window.Closed += CIS_Window_Closed;
}
I am creating a simple application that records input from the microphone and store it into array of bytes. So I have searched a lot about this and eventually ended up using Directx DirectSound. Here is the code I am using:
using Microsoft.DirectX;
using Microsoft.DirectX.DirectSound;
private Thread CaptureSoundThread = null;
public CaptureBuffer applicationBuffer = null;
private SecondaryBuffer soundBuffer = null;
private Device soundDevice = null;
private void Form1_Load(object sender, EventArgs e)
{
soundDevice = new Device();
soundDevice.SetCooperativeLevel(this, CooperativeLevel.Normal);
// Set up our wave format to 44,100Hz, with 16 bit resolution
WaveFormat wf = new WaveFormat();
wf.FormatTag = WaveFormatTag.Pcm;
wf.SamplesPerSecond = 44100;
wf.BitsPerSample = 16;
wf.Channels = 1;
wf.BlockAlign = (short)(wf.Channels * wf.BitsPerSample / 8);
wf.AverageBytesPerSecond = wf.SamplesPerSecond * wf.BlockAlign;
int samplesPerUpdate = 512;
// Create a buffer with 2 seconds of sample data
BufferDescription bufferDesc = new BufferDescription(wf);
bufferDesc.BufferBytes = samplesPerUpdate * wf.BlockAlign * 2;
bufferDesc.ControlPositionNotify = true;
bufferDesc.GlobalFocus = true;
soundBuffer = new SecondaryBuffer(bufferDesc, soundDevice);
}
private void button1_Click(object sender, EventArgs e)
{
CaptureSoundThread = new Thread(new ThreadStart(WaitThread));
CaptureSoundThread.Start();
}
private void WaitThread()
{
while (true)
{
byte[] CaptureData = null;
CaptureData = (byte[])applicationBuffer.Read(0,
typeof(byte), LockFlag.None);
soundBuffer.Write(0, CaptureData, LockFlag.None);
// Start it playing
soundBuffer.Play(0, BufferPlayFlags.Looping);
}
}
But when I try to run the application, I get this annoying error:
BadImageFormatException
Could not load file or assembly 'Microsoft.DirectX.DirectSound.dll' or one
of its dependencies. is not a valid Win32 application. (Exception from
HRESULT: 0x800700C1)
I actually had to download the Microsoft.DirectX.DirectSound.dll from the internet because I couldn't find them in the Visual Studio assemblies.
EDIT : I JUST SOLVED THAT by reading this article : http://www.codeproject.com/Articles/383138/BadImageFormatException-x86-i-x64
EDIT : I JUST SOLVED THAT by reading this article : http://www.codeproject.com/Articles/383138/BadImageFormatException-x86-i-x64
Background: I'm developing an Outlook 2007 Add-in in VS2010 in C#. The specific thing that I'm doing is adding a menu-item to the context menu associated with an email. I do this with the following code:
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
Application.ItemContextMenuDisplay += Application_ItemContextMenuDisplay;
}
private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
{
}
private void Application_ItemContextMenuDisplay(Office.CommandBar commandBar, Outlook.Selection selection)
{
var cmdButtonCallContact = (Office.CommandBarButton)commandBar.Controls.Add(Office.MsoControlType.msoControlButton, 1, System.Reflection.Missing.Value, 6, System.Reflection.Missing.Value);
cmdButtonCallContact.Caption = "&Foo";
//cmdButtonCallContact.Picture = ?
cmdButtonCallContact.Click += cmdButtonCopy_Click;
}
private void cmdButtonCopy_Click(Office.CommandBarButton ctrl, ref bool canceldefault)
{
System.Windows.Forms.MessageBox.Show("Bar");
}
Problem: Can't seem to set the picture. Msdn examples rely on AxHost conversion functions that I don't have. Is there a straightforward way to just set an Image or BitMap to Picture?
Thanks.
If you want a custom image you have to rely on AxHost approach (see MSDN reference) or PictureDispConverter which is another approach created by Microsoft based on OleCreatePictureIndirect.
If you want to use the built-in icons you can just set the FaceId. Download Office Icons Gallery to view Office 2007 FaceId values.
The following code uses a System.Drawing.Bitmap (stored as a Resource) and converts it to an image, that is assignable to Office.CommandBarButton.Picture
private Office.CommandBarButton buttonOne;
void createbutton()
{
Office.CommandBar newMenuBar = Inspector.CommandBars.Add("EAD", Office.MsoBarPosition.msoBarTop, false, true);
buttonOne = (Office.CommandBarButton)newMenuBar.Controls.Add(Office.MsoControlType.msoControlButton, 1, missing, missing, true);buttonOne.Caption = "Ansari";
buttonOne.Style = Office.MsoButtonStyle.msoButtonIconAndWrapCaptionBelow;
buttonOne.Picture = getImage();
//Register send event handler
buttonOne.Click += buttonOne_Click;
newMenuBar.Visible = true;
}
void buttonOne_Click(Office.CommandBarButton Ctrl, ref bool CancelDefault)
{
MessageBox.Show("Hi");
}
private stdole.IPictureDisp getImage()
{
stdole.IPictureDisp tempImage = null;
try
{
System.Drawing.Bitmap newIcon = Properties.Resources.Icon1;
System.Windows.Forms.ImageList newImageList = new System.Windows.Forms.ImageList();
newImageList.Images.Add(newIcon);
tempImage = ConvertImage.Convert(newImageList.Images[0]);
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message);
}
return tempImage;
}
sealed public class ConvertImage : System.Windows.Forms.AxHost
{
private ConvertImage() : base(null)
{
}
public static stdole.IPictureDisp Convert(System.Drawing.Image image)
{
return (stdole.IPictureDisp)System.Windows.Forms.AxHost.GetIPictureDispFromPicture(image);
}
}
Note: Add image with name Icon1 in resource.
Just FYI, if you want to apply any office built-in images to your button (view the image gallery in here), you can simply call GetImageMso() method.
CommandBarButton.Picture = Application.CommandBars.GetImageMso("ImageMSO", 16, 16);
This is an alternative approach to using FaceID property.