How to implement a MultiSelected Photo page in WP8? - windows-phone-8

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());

Related

How to launch app from another app in Windows Phone 8.1

I want to launch my app from another app in the Windows Phone 8.1 environment. I followed the instructions in MSDN, but I cannot figure out how to call the first app from the second. This is the protocol I added in the first app's manifest file:
<Extensions>
<Extension Category="windows.protocol">
<Protocol Name="myapp">
<Logo>Assets\SmallLogo.scale-240.png</Logo>
<DisplayName>my App 1</DisplayName>
</Protocol>
</Extension>
</Extensions>
This is my call from the second app, that does absolutely nothing:
private async void btn_Click(object sender, RoutedEventArgs e)
{
await Windows.System.Launcher.LaunchUriAsync(new System.Uri("myapp:"));
}
Follow the steps in Auto-launching apps using file and URI associations for Windows Phone 8
And you have use use a class which is derived from UriMapperBase to handle the navigation and have to set it as RootFrame.UriMapper in the App.xaml.cs
private void InitializePhoneApplication()
{
if (phoneApplicationInitialized)
return;
// Create the frame but don't set it as RootVisual yet; this allows the splash
// screen to remain active until the application is ready to render.
RootFrame = new PhoneApplicationFrame();
RootFrame.Navigated += CompleteInitializePhoneApplication;
// Assign the URI-mapper class to the application frame.
RootFrame.UriMapper = new AssociationUriMapper();
******
}

How to setup project for Monogame + Windows 8.1?

I'm in the middle of app development with Monogame, and I wanted to add a project for Windows Phone. I have a device with Windows Mobile 8.1 for testing, and I'm using Monogame 3.5 (latest) + VS 2015. But how do I create a project?
The templates for Monogame have several platforms, but the only one for Windows Mobile seems to be Windows 10 Uniwersal Project (UWP). I doubt this would run on WM8.1. Or would it? If not, how do I create the project this otherwise?
Update:
Did more research on this and it seems you need to have minimum Windows 8.1 on your dev PC to develop for Windows Phone 8.1:
https://www.visualstudio.com/en-us/products/visual-studio-2015-compatibility-vs.aspx
So I guess I will just support Android and iOS like all other mobile apps.
Variant 1:
Create win phone 8.1 project
Add NuGet package MonoGame.Framework.WindowsPhone81 (NuGet)
Add standart Game1.cs source code file from Monogame templates
Add in MainPage.xaml.cs
using MonoGame.Framework;
Change in MainPage.xaml.cs
public sealed partial class MainPage : SwapChainBackgroundPanel
{
readonly Game1 _game;
public MainPage(string launchArguments)
{
this.InitializeComponent();
_game = XamlGame<Game1>.Create(launchArguments, Window.Current.CoreWindow, this);
}
}
Change MainPage.xaml (MyGame - default project namespace)
<SwapChainBackgroundPanel
x:Class="MyGame.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MyGame"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid >
</Grid>
</SwapChainBackgroundPanel>
Change App class in App.xaml.cs
protected override void OnLaunched(LaunchActivatedEventArgs args)
{
var gamePage = Window.Current.Content as MainPage;
if (gamePage == null)
{
gamePage = new MainPage(args.Arguments);
if (args.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
}
Window.Current.Content = gamePage;
}
Window.Current.Activate();
}
private void OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral();
deferral.Complete();
}
Add Content.mgcb
Add monogameplatform to project file (.csproj) into PropertyGroup section
<PropertyGroup>
...
<MonoGamePlatform>WindowsStoreApp</MonoGamePlatform>
<MonoGameContentBuilderExe>
</MonoGameContentBuilderExe>
...
</PropertyGroup>
Add next line to project file (.csproj) into Project section
<Import Project="$(MSBuildExtensionsPath)\MonoGame\v3.0\MonoGame.Content.Builder.targets" />
Variant 2: use tool from Protobuild.org

record video by front-camera - WP8 - C#

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..

System.NullReferenceException Windows Phone 8

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.

skydrive api windows phone 8

Has anyone else had an issue with the SkyDrive API for Windows Phone 8? I am upgrading my Windows Phone 7 code to Windows Phone 8. When I click on the Login button (SkyDrive) I get the following screen:
This code (unchanged from WP7) used to work in VS2010.
Is anyone else having this issue? Is there a newer version that I should use (current ver. v2.0.50727)?
Current XAML:
HorizontalAlignment="Left" Margin="308,71,0,0"
Name="signInButton1" VerticalAlignment="Top" Width="160"
ClientId="[myID]" Scopes="wl.skydrive_update"
TextType="SignIn" SessionChanged="btnSignin_SessionChanged"
Branding="Windows"/>
Login code-behind:
private void btnSignin_SessionChanged(object sender, LiveConnectSessionChangedEventArgs e)
{
if (e.Status == LiveConnectSessionStatus.Connected)
{
client = new LiveConnectClient(e.Session);
infoTextBlock.Text = "Signed in.";
client.GetCompleted +=
new EventHandler<LiveOperationCompletedEventArgs>(OnGetCompleted);
client.GetAsync("me", null);
for (var i = 0; i < this.ApplicationBar.Buttons.Count; i++)
{
var button = this.ApplicationBar.Buttons[i] as ApplicationBarIconButton;
if (button != null)
{
if (button.Text == "Upload")
{
button.IsEnabled = true;
}
}
}
}
else
{
infoTextBlock.Text = "Not signed in.";
client = null;
}
}
UPDATE!
I kept on trying and I was still getting this white screen. However, I clicked on the magnifying glass and then hit the back arrow (it resumed) then tried to login again and it worked. So is this just wonky or what?
After further review, I do believe that this is an emulator issue. If I fiddle with it enough, eventually it works.
I read that one cannot use the LiveSDK in the emulator, because you have no MS account in the emulator.
So try to use a physical device for debugging. That works for me.