My issue is quite simple.
I want to turn the flash On (and keep it On) on a Windows 10 universal app project but nothing I try works.
This is the code
MediaCapture MyMediaCapture = new MediaCapture();
var allVideoDevices = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);
DeviceInformation cameraDevice =
allVideoDevices.FirstOrDefault(x => x.EnclosureLocation != null &&
x.EnclosureLocation.Panel == Windows.Devices.Enumeration.Panel.Back);
cameraDevice = cameraDevice ?? allVideoDevices.FirstOrDefault();
if (cameraDevice == null)
{
Debug.WriteLine("No camera device found!");
}
else
{
await MyMediaCapture.InitializeAsync(new MediaCaptureInitializationSettings
{
VideoDeviceId = cameraDevice.Id
});
var MyVideoDeviceController = MyMediaCapture.VideoDeviceController;
var MyTorch = MyVideoDeviceController.TorchControl;
if (MyTorch.Supported)
{
var captureElement = new CaptureElement();
captureElement.Source = MyMediaCapture;
await MyMediaCapture.StartPreviewAsync();
FileStream tmp = new FileStream(System.IO.Path.GetTempFileName() + Guid.NewGuid().ToString() + ".mp4", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None, 10000, FileOptions.RandomAccess | FileOptions.DeleteOnClose);
var videoFile = await KnownFolders.VideosLibrary.CreateFileAsync(tmp.Name, CreationCollisionOption.GenerateUniqueName);
var encodingProfile = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.Wvga);
await MyMediaCapture.StartRecordToStorageFileAsync(encodingProfile, videoFile);
MyTorch.PowerPercent = 100;
MyTorch.Enabled = true;
}
}
Edit: add code
It looks like you're trying to use an old method of accessing the flashlight which we no longer have to use in Windows 10 UWP development. Take a look at the new Lamp feature in Windows.Devices.Lights in this sample on GitHub.
It's a great starting point for using the flash independent of access the camera APIs.
You're on the right path. Depending on the device (because of driver-specific implementations), you'll have to start the preview or maybe even start a video recording session for the light to turn on.
Because of that, and to guarantee compatibility with most devices, I'd recommend you actually do both.
Related
I just converted one of my apps to target Android API 9 (was targeting API 8); now when notifications are sent out, the volume of media is lowered and never comes back to full volume.
The app uses WebView to play media files. This was not happening prior to targeting API 9. I had to convert the app into level 9 so that I could upload to the Google Play Store. I am running a Samsung S7 which was originally designed for API level 6 (with the OS upgraded to 8.0), not sure if that has something to do with the issue. Another detail is that I use Xamarin.Android for development, not sure if that matters either.
Additionally, I forced the notifications to play a blank sound (a very short[couple ms] blank mp3) in the same build that I converted the app to target API 9:
var channelSilent = new Android.App.NotificationChannel(CHANNEL_ID, name + " Silent", Android.App.NotificationImportance.High)
{
Description = description
};
var alarmAttributes = new Android.Media.AudioAttributes.Builder()
.SetContentType(Android.Media.AudioContentType.Sonification)
.SetUsage(Android.Media.AudioUsageKind.Notification).Build()
//blank is blank mp3 file with nothing in it, a few ms in duration
var uri = Android.Net.Uri.Parse("file:///Assets/blank.mp3")
channelSilent.SetSound(uri, alarmAttributes);
...so it could also be the blank sound that is causing the ducking to malfunction, not the API change. Is there something to do with notification sound ducking that could be causing the issue? Is there any other way to mute a notification with Xamarin.Android other than playing a blank sound? That is one route I think would be worth trying to fix this issue.
Here is the code I am using to generate notifications:
private static List<CustomNotification> _sentNotificationList = new List<CustomNotification>();
private static NotificationManagerCompat _notificationManager;
public async void SendNotifications(List<CustomNotification> notificationList)
{
await Task.Run(() =>
{
try
{
var _ctx = Android.App.Application.Context;
if (_notificationManager == null)
{
_notificationManager = Android.Support.V4.App.NotificationManagerCompat.From(_ctx);
}
if (notificationList.Count == 0)
{
return;
}
int notePos = 0;
foreach (var note in notificationList)
{
var resultIntent = new Intent(_ctx, typeof(MainActivity));
var valuesForActivity = new Bundle();
valuesForActivity.PutInt(MainActivity.COUNT_KEY, _count);
valuesForActivity.PutString("URL", note._noteLink);
resultIntent.PutExtras(valuesForActivity);
var resultPendingIntent = PendingIntent.GetActivity(_ctx, MainActivity.NOTIFICATION_ID, resultIntent, PendingIntentFlags.UpdateCurrent);
resultIntent.AddFlags(ActivityFlags.SingleTop);
var alarmAttributes = new Android.Media.AudioAttributes.Builder()
.SetContentType(Android.Media.AudioContentType.Sonification)
.SetUsage(Android.Media.AudioUsageKind.Notification).Build();
//I am playing this blank sound to prevent android from spamming sounds as the notifications get sent out
var uri = Android.Net.Uri.Parse("file:///Assets/blank.mp3");
//if the notification is the first in our batch then use this
//code block to send the notifications with sound
if (!_sentNotificationList.Contains(note) && notePos == 0)
{
var builder = new Android.Support.V4.App.NotificationCompat.Builder(_ctx, MainActivity.CHANNEL_ID + 1)
.SetAutoCancel(true)
.SetContentIntent(resultPendingIntent) // Start up this activity when the user clicks the intent.
.SetContentTitle(note._noteText) // Set the title
.SetNumber(1) // Display the count in the Content Info
.SetSmallIcon(Resource.Drawable.bitchute_notification2)
.SetContentText(note._noteType)
.SetPriority(NotificationCompat.PriorityMin);
MainActivity.NOTIFICATION_ID++;
_notificationManager.Notify(MainActivity.NOTIFICATION_ID, builder.Build());
_sentNotificationList.Add(note);
notePos++;
}
//if the notification isn't the first in our batch, then use this
//code block to send the notifications without sound
else if (!_sentNotificationList.Contains(note))
{
var builder = new Android.Support.V4.App.NotificationCompat.Builder(_ctx, MainActivity.CHANNEL_ID)
.SetAutoCancel(true) // Dismiss the notification from the notification area when the user clicks on it
.SetContentIntent(resultPendingIntent) // Start up this activity when the user clicks the intent.
.SetContentTitle(note._noteText) // Set the title
.SetNumber(1) // Display the count in the Content Info
.SetSmallIcon(Resource.Drawable.bitchute_notification2)
.SetContentText(note._noteType)
.SetPriority(NotificationCompat.PriorityHigh);
MainActivity.NOTIFICATION_ID++;
_notificationManager.Notify(MainActivity.NOTIFICATION_ID, builder.Build());
_sentNotificationList.Add(note);
notePos++;
}
ExtStickyService._notificationsHaveBeenSent = true;
}
}
catch
{
}
});
}
In my MainActivity I've created two different notification channels: one is silent; the other uses default notification setting for the device:
void CreateNotificationChannel()
{
var alarmAttributes = new Android.Media.AudioAttributes.Builder()
.SetContentType(Android.Media.AudioContentType.Sonification)
.SetUsage(Android.Media.AudioUsageKind.Notification).Build();
var uri = Android.Net.Uri.Parse("file:///Assets/blank.mp3");
if (Build.VERSION.SdkInt < BuildVersionCodes.O)
{
// Notification channels are new in API 26 (and not a part of the
// support library). There is no need to create a notification
// channel on older versions of Android.
return;
}
var name = "BitChute";
var description = "BitChute for Android";
var channelSilent = new Android.App.NotificationChannel(CHANNEL_ID, name + " Silent", Android.App.NotificationImportance.High)
{
Description = description
};
var channel = new Android.App.NotificationChannel(CHANNEL_ID + 1, name, Android.App.NotificationImportance.High)
{
Description = description
};
channel.LockscreenVisibility = NotificationVisibility.Private;
//here is where I set the sound for the silent channel... this could be the issue?
var notificationManager = (Android.App.NotificationManager)GetSystemService(NotificationService);
channelSilent.SetSound(uri, alarmAttributes);
notificationManager.CreateNotificationChannel(channel);
notificationManager.CreateNotificationChannel(channelSilent);
}
Full source: https://github.com/hexag0d/BitChute_Mobile_Android_BottomNav/tree/APILevel9
EDIT: something really interesting is that if I pulldown the system ui bar, the volume goes back to normal. Very strange workaround but it might help diagnose the cause.
DOUBLE EDIT: I used .SetSound(null, null) instead of using the blank .mp3 and the ducking works fine now. See comments
I'm implementing a Windows Phone 8.1 App with a QR Code reader. I use ZXing.NET to analyze the taken image and try to parse the QR. To increase it's efficiency I also set autofocus to the camera. It works pretty well at the first start, but not with the second try (f.e. after suspend - resume or restart capturing). As I tested, the FocusAsync method doesn't return sometimes and blocks everything.
What happens here? What could be the problem?
Here is my current code.
Focus
var focusSettings = new Windows.Media.Devices.FocusSettings();
focusSettings.AutoFocusRange = Windows.Media.Devices.AutoFocusRange.Normal;
focusSettings.Mode = Windows.Media.Devices.FocusMode.Auto;
CaptureManager.VideoDeviceController.FocusControl.Configure(focusSettings);
MainProcess
... Initialization ...
ImageEncodingProperties imaggeProperties = ImageEncodingProperties.CreateJpeg();
imaggeProperties.Width = ViewModel.ImageWidth;
imaggeProperties.Height = ViewModel.ImageHeight;
InMemoryRandomAccessStream memoryStream = new InMemoryRandomAccessStream();
LoggingAdapter.Instance.WriteDebugLog("Scanning is in progress. " + Environment.CurrentManagedThreadId);
await CaptureManager.VideoDeviceController.FocusControl.FocusAsync();
await CaptureManager.CapturePhotoToStreamAsync(imaggeProperties, memoryStream);
LoggingAdapter.Instance.WriteDebugLog("Photo captured.");
var bcReader = new BarcodeReader();
... Processing the barcode ...
Cleaning
if (CaptureManager != null)
{
if (InProgress)
{
InProgress = false;
await CaptureManager.StopPreviewAsync();
}
CaptureManager.Dispose();
Capture.Source = null;
}
Thanks for advance!
I succeeded to implement a working solution. I set the the WaitForFocus to false in the FocusSettings and it seems to be working fine, also with suspending or cancelling.
I have developed windows 8.1 store app, it need to be capture photo by using back camera and post.
MediaCaptureInitializationSettings _captureSettings = new var devices = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);
foreach (var device in devices)
{
if (device.EnclosureLocation != null && device.EnclosureLocation.Panel == Windows.Devices.Enumeration.Panel.Back)
{
deviceId = device.Id;
break;
}
}
if (!string.IsNullOrEmpty(deviceId))
{
_captureSettings.AudioDeviceId = "";
_captureSettings.VideoDeviceId = deviceId;
_captureSettings.PhotoCaptureSource = Windows.Media.Capture.PhotoCaptureSource.Photo;
_captureSettings.StreamingCaptureMode = Windows.Media.Capture.StreamingCaptureMode.Video;
}
captureManager = new MediaCapture();
await captureManager.InitializeAsync(_captureSettings);
await captureManager.ClearEffectsAsync(MediaStreamType.Photo);
capturePreview1.Source = captureManager;
await captureManager.StartPreviewAsync();
</code>
Here i am getting two devices but that devices EnclosureLocation is null, so i can't find which one is front and back camera.
so have decided to get second device from list
<code>
deviceId = devices[1].Id;
</code>
but it throws an error like "The current capture source does not have an independent photo stream."
in the line of initializing MediaCapture
<code>
await captureManager.InitializeAsync(_captureSettings);
</code>
i have tried in windows surface pro 2 and acer devices.
Please advise. Thanks in advance.
Try to organise your code better, you got two equals signs on the same line and your code is not well formated so it's hard to read.
To use Camera in Windows 8.1 stop app I use this code :
// First need to find all webcams
DeviceInformationCollection webcamList = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture)
// Then I do a query to find the front webcam
DeviceInformation frontWebcam = (from webcam in webcamList
where webcam.EnclosureLocation != null
&& webcam.EnclosureLocation.Panel == Windows.Devices.Enumeration.Panel.Front
select webcam).FirstOrDefault();
// Same for the back webcam
DeviceInformation backWebcam = (from webcam in webcamList
where webcam.EnclosureLocation != null
&& webcam.EnclosureLocation.Panel == Windows.Devices.Enumeration.Panel.Back
select webcam).FirstOrDefault();
// Then you need to initialize your MediaCapture
var captureManager = new MediaCapture();
await captureManager.InitializeAsync(new MediaCaptureInitializationSettings
{
// Choose the webcam you want (backWebcam or frontWebcam)
VideoDeviceId = backWebcam.Id,
AudioDeviceId = "",
StreamingCaptureMode = StreamingCaptureMode.Video,
PhotoCaptureSource = PhotoCaptureSource.VideoPreview
});
// Set the source of the CaptureElement to your MediaCapture
capturePreview1.Source = captureManager;
// Start the preview
await captureManager.StartPreviewAsync();
This way it's easier to read. The code is not very different, MediaCaptureInitializationSettings is not the same.
This code works for me on Surface 2 RT and Nokia 635 so it should work for you.
Edit:
Seems it works on devices with Windows RT but on full windows 8.1 devices it's always null.
Msdn says that:
If no enclosure location information is available, the property will
be null
so what you can do is first try to see if you find a backwebcam and if it's null take the last one;
DeviceInformation backWebcam = (from webcam in webcamList
where webcam.EnclosureLocation != null
&& webcam.EnclosureLocation.Panel == Windows.Devices.Enumeration.Panel.Back
select webcam).FirstOrDefault();
if (backWebcam == null)
{
backWebcam = webcamList.Last();
}
But you are not sure the last one in the collection is the back one, so you should add a button to let the user switch camera
If you change camera,
await captureManager.StopPreviewAsync();
await captureManager.InitializeAsync(new MediaCaptureInitializationSettings
{
// Choose an other webcam
VideoDeviceId = //id of the new webcam,
AudioDeviceId = "",
StreamingCaptureMode = StreamingCaptureMode.Video,
PhotoCaptureSource = PhotoCaptureSource.VideoPreview
});
await captureManager.StartPreviewAsync();
this way you can be sure the user can choose the right camera even is you programmaticaly cannot tell which one is which
I am creating a Windows Universal application. I want to the user to be able to upload a picture and the user should have the option of taking one on the spot and sending that. I have this working using the MediaCapture api. However I can only seem to use one camera, so for example if my phone has a front and a back camera only the front camera is used. How would I be able to switch the camera that is in use?
I had read something somewhere about using something like this:
private static async Task<DeviceInformation> GetCameraID(Windows.Devices.Enumeration.Panel desired)
{
DeviceInformation deviceID = (await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture))
.FirstOrDefault(x => x.EnclosureLocation != null && x.EnclosureLocation.Panel == desired);
return deviceID;
}
However this always returns null for me, since the deviceID is always null.
Alternatively is there the option of giving control to an application that takes the picture and returns the taken picture to my application? I have found the following, but it doesn't work for Windows Universal apps:
http://msdn.microsoft.com/en-us/library/windows/apps/hh394006(v=vs.105).aspx
Here is how I would do it:
First the initialization part
// First need to find all webcams
DeviceInformationCollection webcamList = await DeviceInformation.FindAllAsync(DeviceClass.All)
// Then I do a query to find the front webcam
DeviceInformation frontWebcam = (from webcam in webcamList
where webcam.EnclosureLocation != null
&& webcam.EnclosureLocation.Panel == Windows.Devices.Enumeration.Panel.Front
select webcam).FirstOrDefault();
// Same for the back webcam
DeviceInformation backWebcam = (from webcam in webcamList
where webcam.EnclosureLocation != null
&& webcam.EnclosureLocation.Panel == Windows.Devices.Enumeration.Panel.Back
select webcam).FirstOrDefault();
// Then you need to initialize your MediaCapture
newCapture = new MediaCapture();
await newCapture.InitializeAsync(new MediaCaptureInitializationSettings
{
// Choose the webcam you want
VideoDeviceId = backWebcam.Id,
AudioDeviceId = "",
StreamingCaptureMode = StreamingCaptureMode.Video,
PhotoCaptureSource = PhotoCaptureSource.VideoPreview
});
// Set the source of the CaptureElement to your MediaCapture
// (In my XAML I called the CaptureElement *Capture*)
Capture.Source = newCapture;
// Start the preview
await newCapture.StartPreviewAsync();
Secondly take the picture
//Set the path of the picture you are going to take
StorageFolder folder = ApplicationData.Current.LocalFolder;
var picPath = "\\Pictures\\newPic.jpg";
StorageFile captureFile = await folder.CreateFileAsync(picPath, CreationCollisionOption.GenerateUniqueName);
ImageEncodingProperties imageProperties = ImageEncodingProperties.CreateJpeg();
//Capture your picture into the given storage file
await newCapture.CapturePhotoToStorageFileAsync(imageProperties, captureFile);
That should solve your problem.
Can anyone say how to toggle flashlight in Windows Phone 8.1 using C#? It seems like there are lots of API changes in Windows Phone 8.1 and most of the API's in WP 8.0 are not supported. Answers are highly appreciated.
I'm able to use TorchControl on my Lumia 820 like this - first you have to specify which camera you will use - the default is front (I think that's why you may find some problems) and we want the back one - the one with flash light. Sample code:
// edit - I forgot to show GetCameraID:
private static async Task<DeviceInformation> GetCameraID(Windows.Devices.Enumeration.Panel desiredCamera)
{
DeviceInformation deviceID = (await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture))
.FirstOrDefault(x => x.EnclosureLocation != null && x.EnclosureLocation.Panel == desiredCamera);
if (deviceID != null) return deviceID;
else throw new Exception(string.Format("Camera of type {0} doesn't exist.", desiredCamera));
}
// init camera
async private void InitCameraBtn_Click(object sender, RoutedEventArgs e)
{
var cameraID = await GetCameraID(Windows.Devices.Enumeration.Panel.Back);
captureManager = new MediaCapture();
await captureManager.InitializeAsync(new MediaCaptureInitializationSettings
{
StreamingCaptureMode = StreamingCaptureMode.Video,
PhotoCaptureSource = PhotoCaptureSource.VideoPreview,
AudioDeviceId = string.Empty,
VideoDeviceId = cameraID.Id
});
}
// then to turn on/off camera
var torch = captureManager.VideoDeviceController.TorchControl;
if (torch.Supported) torch.Enabled = true;
// turn off
if (torch.Supported) torch.Enabled = false;
Note that it's a good idea to call captureManager.Dispose() after you finish with it.
Note also that on some phones to turn on torch/flashlight you will need to start preview first.
Windows Phone 8.1 is the first version with a dedicated API for controlling the camera light. This API stems from Windows 8.1 but is usable in Windows Phone 8.1 projects and in Windows Phone Silverlight 8.1 projects.
var mediaDev = new MediaCapture();
await mediaDev.InitializeAsync();
var videoDev = mediaDev.VideoDeviceController;
var tc = videoDev.TorchControl;
if (tc.Supported)
{
if (tc.PowerSupported)
tc.PowerPercent = 100;
tc.Enabled = true;
}
Note:
Note: TorchControl.Supported returns false on most phones in WP8.1 developer preview. It is expected to be fixed by a firmware update by the time WP 8.1 is released. Tested Phones at the time of writing: Lumia 620, 822, 1020: not working, Lumia 1520: working.
In Nokia Lumia 1520, you use FlashControl to toggle the flash light instead of TorchControl.
//to switch OFF flash light
mediacapture.VideoDeviceController.FlashControl.Enabled = false;
//to switch ON flash light
mediacapture.VideoDeviceController.FlashControl.Enabled = true;
Doesn't work on my Lumia 1520. You need to start video recording to get flashlight working:
var videoEncodingProperties = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.Vga);
var videoStorageFile = await KnownFolders.VideosLibrary.CreateFileAsync("tempVideo.mp4", CreationCollisionOption.GenerateUniqueName);
await captureManager.StartRecordToStorageFileAsync(videoEncodingProperties, videoStorageFile);
In my Lumia 1520. I need to start video recording and start preview to get flashlight working:
await captureManager.StartPreviewAsync();