I am experiencing a strange issue, since normally this works like a charm on Windows Phone 7. I just upgraded the project to Windows Phone 8 for getting the XAP file, it crashes.
This is the part of the code which "fails":
/// Holds the push channel that is created or found.
HttpNotificationChannel pushChannel;
// The name of our push channel.
string channelName = "ToastSampleChannel";
InitializeComponent();
// Try to find the push channel.
pushChannel = HttpNotificationChannel.Find(channelName);
// If the channel was not found, then create a new connection to the push service.
if (pushChannel == null)
{
pushChannel = new HttpNotificationChannel(channelName);
// Register for all the events before attempting to open the channel.
pushChannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(PushChannel_ChannelUriUpdated);
pushChannel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>(PushChannel_ErrorOccurred);
// Register for this notification only if you need to receive the notifications while your application is running.
//pushChannel.ShellToastNotificationReceived += new EventHandler<NotificationEventArgs>(PushChannel_ShellToastNotificationReceived);
pushChannel.Open();
// Bind this new channel for toast events.
pushChannel.BindToShellToast();
}
else
{
// The channel was already open, so just register for all the events.
pushChannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(PushChannel_ChannelUriUpdated);
pushChannel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>(PushChannel_ErrorOccurred);
// Register for this notification only if you need to receive the notifications while your application is running.
//pushChannel.ShellToastNotificationReceived += new EventHandler<NotificationEventArgs>(PushChannel_ShellToastNotificationReceived);
// Display the URI for testing purposes. Normally, the URI would be passed back to your web service at this point.
System.Diagnostics.Debug.WriteLine(pushChannel.ChannelUri.ToString());
// MessageBox.Show(String.Format("Channel Uri is {0}", pushChannel.ChannelUri.ToString()));
}
string token = pushChannel.ChannelUri.ToString();
//System.Diagnostics.Debug.WriteLine("token");
//System.Diagnostics.Debug.WriteLine(token);
//int active = 1;
object uniqueID;
string deviceID;
if (Microsoft.Phone.Info.DeviceExtendedProperties.TryGetValue("DeviceUniqueId", out uniqueID) == true)
{
WB1.Navigated += WB1_Navigated;
//getting udid
byte[] bID = (byte[])uniqueID;
deviceID = Convert.ToBase64String(bID); // There you go
}
When it crash, the next line in being execute would be WB1.Navigated += WB1_Navigated;
So I think the error is in the previous if-condition, but I am not able to see what is wrong because before upgrading the target in project properties, it worked fine.
Any idea?
I add WB1_Navigated and other related methods:
void WB1_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
{
visitedUrls.Push(e.Uri);
}
private void WebBrowser_OnLoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)
{
this.CoverImage.Visibility = Visibility.Collapsed;
}
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
if (visitedUrls.Count > 1)
{
visitedUrls.Pop();
WB1.Navigate(visitedUrls.Pop());
e.Cancel = true;
}
}
As petition, I show my xml code:
<phone:PhoneApplicationPage
x:Class="WindowsPush.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True" d:DesignHeight="768" d:DesignWidth="480">
<!--LayoutRoot is the root grid where all page content is placed-->
<!--Sample code showing usage of ApplicationBar-->
<!--<phone:PhoneApplicationPage.ApplicationBar>
<shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
<shell:ApplicationBarIconButton IconUri="/Images/appbar_button1.png" Text="Button 1"/>
<shell:ApplicationBarIconButton IconUri="/Images/appbar_button2.png" Text="Button 2"/>
<shell:ApplicationBar.MenuItems>
<shell:ApplicationBarMenuItem Text="MenuItem 1"/>
<shell:ApplicationBarMenuItem Text="MenuItem 2"/>
</shell:ApplicationBar.MenuItems>
</shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<phone:WebBrowser Name="WB1" LoadCompleted="WebBrowser_OnLoadCompleted"/>
<Image x:Name="CoverImage" Width="Auto" Height="Auto" Source="\SplashScreenImage.jpg"></Image>
</Grid>
</phone:PhoneApplicationPage>
You are getting (probably) your Exception in line:
string token = pushChannel.ChannelUri.ToString();
You get your ChanelUri after some time, and before you get it it's null. Move your token to PushChannel_ChannelUriUpdated:
private void PushChannel_ChannelUriUpdated(object sender, NotificationChannelUriEventArgs e)
{
string token = pushChannel.ChannelUri.ToString();
}
EDIT - source information
According to this blog:
The Open channel (a few lines of code later) is an asynchronous operation (therefore the need to attach an event handler that gets triggered once the open operation completes). If it is successful, the ChannelUriUpdate event is raised, if it fails, most probably HttpNotificationChannel will raise an ExceptionOccurred event.
Related
I am unable to receive raw notification on my WindowsPhone8.
Followed :https://github.com/barryvdh/PushPlugin/#uccb-wp8-only
Able to get toast notification. In my app toggle is happening like below.
Case 1: If I comment ecb able to get both raw and toast but not
channel uri.
Case 2: If I won't comment ecb able to get toast and channel uri but
not raw
My code as follows:
if (device.platform == "Win32NT") {
console.log("called");
pushNotification.register(
channelHandler,
errorHandler,
{
"channelName": "channelName",
"ecb": onNotificationWP8,
"uccb": channelHandler,
"errcb": jsonErrorHandler
});
}
else {
console.log("not called");
}
}
function channelHandler(event) {
var uri = event.uri;
console.log("UUUUURRRRRRRRRRRIIIIIIIII :" + uri);
}
function errorHandler(e) {
}
function jsonErrorHandler(error) {
$("#app-status-ul").append('<li style="color:red;">error:' + error.code + '</li>');
$("#app-status-ul").append('<li style="color:red;">error:' + error.message + '</li>');
}
function onNotificationWP8(e) {
console.log("notification called");
if (e.type == "toast" && e.jsonContent){
pushNotification.showToastNotification(successHandler, errorHandler,
{
"Title": e.jsonContent["wp:Text1"], "Subtitle": e.jsonContent["wp:Text2"], "NavigationUri": e.jsonContent["wp:Param"]
});
}
if (e.type == "raw" && e.jsonContent) {
alert(e.jsonContent.Body);
}
}
Tried with error and trail methods. Please suggest what might went wrong.
The issue observed does not appear to be related to Worklight at all. From the description and the code snippet, you are bypassing Worklight client SDK and server completely , and using a custom Cordova Push plugin. The custom plugin's working in your application should be analyzed to understand the variance in behaviour.
Since you are not using Worklight Push at all, you can try disabling it and check if this helps your case.
To do this, navigate to the config.xml . This will be located in apps/YourAppName/WindowsPhone8/native/Resources folder.
Look for :
<feature name="Push">
<param name="wp-package" value="Push" />
</feature>
Change this to:
<feature name="Push">
<param name="wp-package" value="Push" />
<param name="onload" value="false" />
</feature>
On the query regarding Worklight API:
There are no Worklight APIs that return Channel URI. When using Worklight SDK for Push, all this is done automatically and hidden from the user. Even with a Push Adapter in place, it is not possible to obtain the channel URI as there no APIs published to obtain this information.
Finally it got solved by adding Coding4Fun.Toolkit.Controls.dll
And some code updation in PushPlugin.cs
using Coding4Fun.Toolkit.Controls;
using System.Windows.Threading;
void PushChannel_ShellToastNotificationReceived(object sender, NotificationEventArgs e)
{
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
string msg = string.Empty;
foreach (var item in e.Collection)
{
if (item.Key == "wp:Text1")
{
msg = item.Value;
}
}
MessageBox.Show(msg, "Notification", MessageBoxButton.OK);
});
}
My heart-full thanks to Rajith who helped me to make it happen.
My windows phone app needs to record a video from front-camera and send it to the server through a webservice.
Here while I'm trying to record video from front-camera, I'm getting mirror inverted video. Means front-camera records 180 degree rotated video.
what i think probably the only solution of it is to rotate the recorded video stream to 180 degree back.
Question:
is there any other solution to record proper video by front-camera in wp8?
if not, how to rotate the video stream 180 degree? any c# API to do it..?
Edit:
Here is code that I'm using:
XAML code for VideoBrush
<Canvas x:Name="CanvasLayoutRoot" RenderTransformOrigin="0.5 0.5"
Width="{Binding ActualHeight, ElementName=LayoutRoot}"
Height="{Binding ActualWidth, ElementName=LayoutRoot}"
Margin="-160 0 0 0">
<!--Background="Transparent"-->
<Canvas.Background>
<VideoBrush x:Name="videoBrush" />
</Canvas.Background>
<Canvas.RenderTransform>
<RotateTransform x:Name="rt" />
</Canvas.RenderTransform>
</Canvas>
Initializing camera
public async void InitializeVideoRecorder()
{
try
{
if (videoCapture == null)
{
// below line of code will detect if "Front Camera" is available or not
// if availble, then open it or it will open "Back Camera"
videoCapture = await AudioVideoCaptureDevice.OpenAsync(
AudioVideoCaptureDevice.AvailableSensorLocations.Contains(CameraSensorLocation.Front) ? CameraSensorLocation.Front : CameraSensorLocation.Back,
new Windows.Foundation.Size(640, 480));
videoCapture.RecordingFailed += videoCapture_RecordingFailed;
videoCapture.SetProperty(KnownCameraGeneralProperties.EncodeWithOrientation, videoCapture.SensorRotationInDegrees);
// Initialize the camera if it exists on the phone.
if (videoCapture != null)
{
videoBrush.SetSource(videoCapture);
if (!AudioVideoCaptureDevice.AvailableSensorLocations.Contains(CameraSensorLocation.Front))
{
rt.Angle = videoCapture.SensorRotationInDegrees;
}
else
{
rt.Angle = -(videoCapture.SensorRotationInDegrees);
}
}
else
{
MessageBox.Show("Unable to load Camera. Please try again later.", App.appName, MessageBoxButton.OK);
NavigationService.GoBack();
}
}
}
catch (Exception ex)
{
(new WebServices()).catchExceptions(ex);
NavigationService.GoBack();
}
}
Starting VideoCapture
private async Task StartVideoRecording()
{
try
{
// Gets the application data folder
StorageFolder applicationFolder = ApplicationData.Current.LocalFolder;
StorageFolder transfersFolder = await (await applicationFolder.GetFolderAsync("Shared")).GetFolderAsync("Transfers");
// Create the file specified in the application data folder
videoFileName = selectedQue.response.template_id + "_" + selectedQue.response.id + "_" + selectedQue.response.invite_id +".mp4";
StorageFile storageFile = await transfersFolder.CreateFileAsync(videoFileName, CreationCollisionOption.ReplaceExisting);
// Open a file stream, ready to write video data
randomAccessStream = await storageFile.OpenAsync(FileAccessMode.ReadWrite);
// Video recording to the specified stream
await videoCapture.StartRecordingToStreamAsync(randomAccessStream);
isRecordingStarted = true;
//timer = "0:00";
tbTimer.Text = "0:00";
dt.Start();
}
catch (Exception ex)
{
(new WebServices()).catchExceptions(ex);
}
}
This worked for me in the past, it was just a barcode scanner app that I coded up to fulfill a functional requirement. I put the transform on the <VideoBrush>.
<Grid x:Name="ContentPanel" Margin="12,0,12,0">
<Canvas x:Name="cam_canvas" Width="480" Height="480">
<Canvas.Background>
<VideoBrush x:Name="cam_video_brush" Stretch="None">
<VideoBrush.RelativeTransform>
<CompositeTransform Rotation="90" CenterX="0.5" CenterY="0.5" />
</VideoBrush.RelativeTransform>
</VideoBrush>
</Canvas.Background>
</Canvas>
</Grid>
Finally i solved my problem after 24 hours of efforts with below solution.
The line of code that causing issue by rotating video was below.
videoCapture.SetProperty(KnownCameraGeneralProperties.EncodeWithOrientation, videoCapture.SensorRotationInDegrees);
here videoCapture is object of AudioVideoCaptureDevice
While using front camera, we need to invert the rotation of cameraSensor.
So I've used the above same code (mentioned in question) with one tiny modification in this videoCapture.SetProperty line of code. the correct line of code is as below.
videoCapture.SetProperty(KnownCameraGeneralProperties.EncodeWithOrientation, -(videoCapture.SensorRotationInDegrees));
I just inverted the videoCapture.SensorRotationInDegrees by adding one minus sign (-) before it.
Hope this helps all..
I know that now in Windows Phone 8.1 and Windows 8.1, it's easy to choose multi-photos using FileOpenPicker.
But in Windows Phone 8.0, only native code have access to the API, so if we have to choose multi-photos to do something(that is ,like uploading), we have to implemenet it by toolkit:LongListMultiSelector .
By doing this, I have a performance problem.
Here is the XAML:
<ScrollViewer x:Name="ScrowllViewAlbum" HorizontalAlignment="Left" Height="500" VerticalAlignment="Top" Width="458" >
<toolkit:LongListMultiSelector
x:Name="AlbumList"
IsGroupingEnabled="False"
GridCellSize="100,100"
LayoutMode="Grid"
HideEmptyGroups="True"
IsSelectionEnabled="False"
EnforceIsSelectionEnabled="False"
CacheMode="BitmapCache"
ItemsSource="{Binding}"
Width="459"
ItemTemplate="{StaticResource AllPhotoTemplete}" Background="Black"
/>
</ScrollViewer>
and in ViewModel:
public void LoadAllPhotos()
{
Allphotos = new ObservableCollection<BitmapImage>();
MediaLibrary medialib = new MediaLibrary();
PictureCollection pics = medialib.Pictures;
if (pics.Count!=0)
{
BitmapImage image = new BitmapImage();
foreach(var pic in pics)
{
Stream stream = pic.GetImage();
image.SetSource(stream);
Allphotos.Add(image);
}
}
}
However, during the debug, it throw out an exception of no insufficient memory.
Can you give me some idea to optimize the function?
Thanks :-)
There is no other way then implement the picker yourself.
since you are only loading the images for a preview, only load the thumbnail like:
var image = new BitmapImage();
image.SetSource(pic.GetThumbnail());
I have followed all the steps given in the documentation to register for a push notification from the Parse website. (All the steps in the sense I downloaded the default project and added event handler to handle the incoming toast notification).
ParseClient.Initialize("x0uNa3Q164SVGKbH4mxZJaxWxsuYtslB5tVPj893",
"cXFv9RQAoray9xFdwdcZCHXrrkrM6KNd0WyN194H");
this.Startup += async (sender, args) =>
{
// This optional line tracks statistics around app opens, including push effectiveness:
ParseAnalytics.TrackAppOpens(RootFrame);
// By convention, the empty string is considered a "Broadcast" channel
// Note that we had to add "async" to the definition to use the await keyword
await ParsePush.SubscribeAsync("");
};
ParsePush.ToastNotificationReceived += ParsePushOnToastNotificationReceived;
and the handler
private void ParsePushOnToastNotificationReceived(object sender,
NotificationEventArgs notificationEventArgs)
{
var s = new ShellToast();
s.Content = notificationEventArgs.Collection.Values.First();
s.Title = "My Toast";
s.Show();
}
private async void Application_Launching(object sender, LaunchingEventArgs e)
{
await ParseAnalytics.TrackAppOpenedAsync();
}
When I run the app in the emulator it registers the app and I can verify it in my dashboard. But as soon as I send push notification from the website number of registered devices will be shown as 0 and the app doesnt receive the notification.
One thing to mention is this behavior is not consistent. Sometimes the app does receive the notification. Can anyone mention the reason for this or any other point I am missing?
One thing to note is that ShellToast.Show() should only be used from background task. If you call it when an app is in the foreground, toast won't be shown. http://msdn.microsoft.com/en-US/library/windowsphone/develop/microsoft.phone.shell.shelltoast.show(v=vs.105).aspx
So, be sure your app is not in the foreground when you expect to see toast notification.
Firstly you will be shown toast notification only if the foreground app is not running. If your app is running when you receive push notification you have to do like:
void ParsePushOnToastNotificationReceived(object sender,
NotificationEventArgs notificationEventArgs)
{
Deployment.Current.Dispatcher.BeginInvoke(()=>{
// do anything
MessageBox.Show("got notification");
});
}
If your app is not running the os will handle the notification properly, you dont have to do anything.
In the code below the documents folder is not shown to pick a file. The capabilities have been set correctly (I think) otherwise an Exception would be thrown. If I set a breakpoint I see that the code reaches the await statement but then it sits there and nothing happens.
Private Async Function Button_Click_1(sender As Object, e As RoutedEventArgs) As Task
If ApplicationView.TryUnsnap = False Then
StatusMessage = "Cannot unsnap."
Exit Function
End If
Dim filePicker As New FileOpenPicker
filePicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary
filePicker.ViewMode = PickerViewMode.Thumbnail
filePicker.FileTypeFilter.Add(".pbn")
Dim pbnFile = Await filePicker.PickSingleFileAsync
If pbnFile IsNot Nothing Then
StatusMessage = pbnFile.Path
End If
End Function
EDIT: the first line in the Method above must be:
If ApplicationView.Value = ApplicationViewState.Snapped AndAlso ApplicationView.TryUnsnap = False Then
And the problem is solved...
The XAML:
<Page
x:Class="HandEditor.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:HandEditor"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Button Click="Button_Click_1">Choose .pbn file</Button>
<TextBlock Grid.Row="1" Text="{Binding StatusMessage}"/>
</Grid>
</Page>
This is because your call to unsnap is failing.
Try snapping your app, then it will work as expected. Remove the exit function part and it works as expected.