Windows Phone 8.1 Share Contract - c#

I wrote a Windows Phone 8.1 (WINRT) App. I am trying to share an image from my app which is in LocalStorage of the app. I am using Windows Phone 8.1 Share Contract.
private async void OnShareDataRequested(DataTransferManager sender, DataRequestedEventArgs _dataRequestedEventArgs)
{
_dataRequestedEventArgs.Request.GetDeferral();
List<StorageFile> ListObject = new List<StorageFile>();
Uri UriObject = new Uri(FileLocation,UriKind.RelativeOrAbsolute);
_dataRequestedEventArgs.Request.Data.Properties.Title = "Dr. App";
_dataRequestedEventArgs.Request.Data.Properties.Description = "Photo from my Dr. App Album.";
StorageFolder StorageFolderObject;
StorageFile StorageFileObject;
try
{
StorageFolderObject = await Windows.Storage.ApplicationData.Current.LocalFolder.GetFolderAsync(LocalCache);
StorageFileObject = await StorageFolderObject.GetFileAsync(FileNameSaved);
_dataRequestedEventArgs.Request.Data.Properties.Thumbnail = RandomAccessStreamReference.CreateFromFile(StorageFileObject);
_dataRequestedEventArgs.Request.Data.SetBitmap(RandomAccessStreamReference.CreateFromFile(StorageFileObject));
ListObject.Add(StorageFileObject);
_dataRequestedEventArgs.Request.Data.SetStorageItems(ListObject);
}
catch(Exception ex_)
{
}
finally
{
_dataRequestedEventArgs.Request.GetDeferral().Complete();
}
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
DataTransferManager.GetForCurrentView().DataRequested -= OnShareDataRequested;
base.OnNavigatedFrom(e);
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
DataTransferManager.GetForCurrentView().DataRequested += OnShareDataRequested;
base.OnNavigatedTo(e);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
DataTransferManager.ShowShareUI();
}
I am getting PREPARING CONTENT TO SHARE and then it vanishes in a second. ShareUI doesnt open.

The documentation states that the asynchronous work has an upper limit of 200 ms. Are you violating this premise?
DataRequest.GetDeferral(): Use this method when you want to use an asynchronous function call to generate the DataPackage during a share operation. This function must return a DataPackage object within 200ms to prevent the operation from timing out. If your app shares content that takes more time to package, such as a collection of files or photos, don't use this method. Instead, use the SetDataProvider method to assign a delegate to a DataPackage and return that DataPackage to the target app.
Another thing that stands out to me when I look at your code is that you invoke the GetDeferral method twice instead of saving the result from the first invocation.

Related

Windows phone 8.1 universal app DataTransferManager UI not showing

In my windows phone 8.1 universal app project I am trying to make a share option.
But when I click on the button (ShareCommand) the Share UI is not showing up, I have tried this in the emulator and on a device.
The event is correctly wired up since the DataRequested event gets called, but after this event there is no Share UI showing.
Here is the code I use in my ViewModel (using prism framework).
private DataTransferManager _dataTransferManager;
private DelegateCommand _shareCommand;
// Share button
public DelegateCommand ShareCommand
{
get
{
return _shareCommand ?? (_shareCommand = new DelegateCommand(() =>
{
DataTransferManager.ShowShareUI();
}));
}
}
public override async void OnNavigatedTo(object navigationParameter, NavigationMode navigationMode, Dictionary<string, object> viewModelState)
{
base.OnNavigatedTo(navigationParameter, navigationMode, viewModelState);
// get data transfer manager and register events
_dataTransferManager = DataTransferManager.GetForCurrentView();
_dataTransferManager.DataRequested += DataTransferMangerDataRequested;
_dataTransferManager.TargetApplicationChosen += DataTransferMangerTargetApplicationChosen;
}
public override void OnNavigatedFrom(Dictionary<string, object> viewModelState, bool suspending)
{
base.OnNavigatedFrom(viewModelState, suspending);
// clean up events
_dataTransferManager.DataRequested -= DataTransferMangerDataRequested;
_dataTransferManager.TargetApplicationChosen -= DataTransferMangerTargetApplicationChosen;
}
private void DataTransferMangerTargetApplicationChosen(DataTransferManager sender, TargetApplicationChosenEventArgs args)
{
}
private void DataTransferMangerDataRequested(DataTransferManager sender, DataRequestedEventArgs args)
{
var request = args.Request;
var deferral = request.GetDeferral();
request.Data.Properties.Title = "title test";
request.Data.Properties.Description = "description test";
request.Data.SetText("test hello");
request.Data.SetUri(new Uri("https://www.google.com"));
request.FailWithDisplayText("fail");
deferral.Complete();
}
I have tried setting different properties in the DataRequested event but still nothing.
Does anyone know what it could be? Do I need to set some permissions?
Edit:
Ok, weird I tried this in a new solution with only this code and it is working fine. But no idea why its not working in my current solution.
Ok I found out what was causing the problem.
I had to remove this, since this will cancel the operation. (I thought this will show if it failed for some reason and not cancel directly).
request.FailWithDisplayText("fail");

MediaElement working within WPF but not within Windows 8.1 App

The code shown below, which plays an audio file, runs fine within my WPF application. But when I execute the same code within a Windows 8.1 app, I am not getting any exceptions but I am also receiving no sound. Can anyone help?
private void myMediaElement_MediaOpened(object sender, RoutedEventArgs e)
{
myMediaElement.Source =
new Uri(#"C:\Users\Soph\Music\Addicted.mp3", UriKind.Absolute);
myMediaElement.Play();
}
private void btn1_Click(object sender, RoutedEventArgs e)
{
myMediaElement_MediaOpened(sender,e);
}
EDIT:
I have added per the advice the mediaFailed event (followed from http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.controls.mediaelement.mediafailed)
private string GetHresultFromErrorMessage(ExceptionRoutedEventArgs e)
{
String hr = String.Empty;
String token = "HRESULT - ";
const int hrLength = 10; // eg "0xFFFFFFFF"
int tokenPos = e.ErrorMessage.IndexOf(token, StringComparison.Ordinal);
if (tokenPos != -1)
{
hr = e.ErrorMessage.Substring(tokenPos + token.Length, hrLength);
}
return hr;
}
private void mycontrol_MediaFailed(object sender, ExceptionRoutedEventArgs e)
{
// get HRESULT from event args
string hr = GetHresultFromErrorMessage(e);
// Handle media failed event appropriately
}
Then i tried to debug this:
Name Value Type
this {PracMEWindowsApp.MainPage} PracMEWindowsApp.MainPage
e {Windows.UI.Xaml.ExceptionRoutedEventArgs} Windows.UI.Xaml.ExceptionRoutedEventArgs
hr "0x80070003" string
token "HRESULT - " string
tokenPos 40 int
hrLength 10 int
What is this hr capturing ? Why is my file not played ?
To access the Music library specify the Music Library capability in app manifest. It is also good practice to always handle the MediaFailed event.
HRESULT 0x80070003 is "Directory Not Found". That would suggest that the media element doesn't like something about the file path. If you get HRESULT 0x80070005 (Access Denied), then it's probably a permissions-related thing.
Windows Store app does not have access to files in local file system, it runs in a sandboxed environment and only has access to its own data folder, a path like C:\Users\Soph\Music\Addicted.mp3 is unrecognizable.
There are several ways in which you can play the media file.
a.Specify the Music Library capability in Package.appxmanifest (this is required), and then
private async void btn1_Click(object sender, RoutedEventArgs e)
{
var file = await Windows.Storage.KnownFolders.MusicLibrary.GetFileAsync("Addicted.mp3");
var stream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
myMediaElement.SetSource(stream, file.ContentType);
}
or
b. use FileOpenPicker, choose the song manually, you can access any .mp3 file in the file system.
private async void btn1_Click(object sender, RoutedEventArgs e)
{
FileOpenPicker openPicker = new FileOpenPicker();
openPicker.FileTypeFilter.Add(".mp3");
openPicker.SuggestedStartLocation = PickerLocationId.MusicLibrary;
var file = await openPicker.PickSingleFileAsync();
var stream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
myMediaElement.SetSource(stream, file.ContentType);
}
or
c. Add Addicted.mp3 to your project, and then
Uri uri = new Uri("ms-appx:///Addicted.mp3");
myMediaElement.Source = uri;
you can also set it in XAML
<MediaElement x:Name="myMediaElement" Source="Addicted.mp3" />

Save data on exit Windows Phone 8.1 (Universal Apps)

I have a question regarding saving/loading data in Windows Universal Apps 8.1.
I cannot seem to save the data when exiting the app. My call to the serialization is done in the OnSuspending method in App.xaml.cs, but I don't think it is called whenever I close the app.
It sometimes saves the data, sometimes not. Here is my code for OnSuspending and Save methods.
private void OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral();
// TODO: Save application state and stop any background activity
Debug.WriteLine("SUSPENDING");
HabitManager.HabitSerializer.Save();
deferral.Complete();
}
public async static void Save()
{
Debug.WriteLine("SAVED");
var json = JsonConvert.SerializeObject(HabitList.Instance.GetHabits());
var habits = HabitList.Instance.GetHabits();
foreach (var h in habits)
{
Debug.WriteLine("S: " + h);
}
StorageFile saveFile = await folder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
await Windows.Storage.FileIO.WriteTextAsync(saveFile, json);
}
So my question is, what could be the problem, and if this isn't a good serializing mechanism, can you suggest me a better one? Thank you
Your OnSuspending call returns before the Save call finishes.
Change Save to return a Task so you can await it:
private void OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral();
// TODO: Save application state and stop any background activity
Debug.WriteLine("SUSPENDING");
// Wait fir Save to finish its a sync operations
await HabitManager.HabitSerializer.Save();
deferral.Complete();
}
public async static Task Save()
{
// Same save code
}
Also be careful when testing suspension. The app won't suspend normally while debugging, but VS provides a suspend button to simulate the suspension process.

Calling webservice on windows phone

How to Calling the webservice without using the function service_GetItemInfoCompleted() in the below code?
Can it get the result without the function service_GetItemInfoCompleted().
Any idea?
private void btnFind_Click(object sender, RoutedEventArgs e)
{
Service1Client service = new Service1Client();
service.GetItemInfoAsync(txt1.Text);
service.GetItemInfoCompleted += new EventHandler<GetItemInfoCompletedEventArgs>(service_GetItemInfoCompleted);
}
void service_GetItemInfoCompleted(object sender, GetItemInfoCompletedEventArgs e)
{
txb1.Text = e.Result;
}
Example 2
public void running()
{
ServiceReference1.WebServiceSoapClient test = new ServiceReference1.WebServiceSoapClient();
test.ReadTotalOutstandingInvoiceCompleted += new EventHandler<ServiceReference1.ReadTotalOutstandingInvoiceCompletedEventArgs>(serviceClient);
test.ReadTotalOutstandingInvoiceAsync();
}
public void serviceClient(object sender, ReadTotalOutstandingInvoiceCompletedEventArgs e)
{
answer = int.parse(e.Result.ToString());
}
The above approach is the correct approach: Send the request to the service and when it returns, display the returned data in your textbox.
If you performed the same operation in one blocking call ...
private void btnFind_Click(object sender, RoutedEventArgs e)
{
Service1Client service = new Service1Client();
txtb1.Text = service.GetItemInfoAsync(txt1.Text);
}
... then your main UI thread would block until the data is returned from the service. If the service took several seconds to return, then your app's UI would 'hang' intermittently for several seconds, giving your users a very poor experience. This is a bad thing to do and something to avoid at all cost!
So we want to asynchronously call your service and wait for it to return without blocking threads. But rather than write the async code by hand, we can use the new async & await keywords in C# 5.0 to achieve the same goal as above but with less code & complexity:
private async void btnFind_Click(object sender, RoutedEventArgs e)
{
Service1Client service = new Service1Client();
string result = await service.GetItemInfoAsync(txt1.Text);
txtb1.Text = result;
}
Note the use of async and await in the code above. The async keyword tells the compiler that you want it to build a state-machine which is driven by await states. Each await keyword tells the compiler to add a new state to the state-machine. When the code is executed, the await code sets up the state-machine to pick-up at the next operation when the awaited-upon task (service.GetItemInfoAsync() in this case) completes.
HTH.

How to use ApplicationStateModel class of .net Metro style app?

I want to save the application state when an metro style app receive the suspend event.
I found in this link the code below, but I donĀ“t find in .Net the class ApplicationStateModel:
public App()
{
InitializeComponent();
this.Suspending += new SuspendingEventHandler(App_Suspending);
this.Resuming += new Windows.UI.Xaml.EventHandler(App_Resuming);
}
void App_Resuming(object sender, object e)
{
// Write code to update ui only for items that are outdated.
// This is resume from suspended state, so it does not lose any data
}
async void App_Suspending(object sender, Windows.ApplicationModel.SuspendingEventArgs e)
{
// Write code to store data so that when the application is terminated the state can be recovered.
// Allowed only 5 seconds to do the storage
SuspendingDeferral deferral = e.SuspendingOperation.GetDeferral();
await **ApplicationStateModel**.SaveAllApplicationDataAsync();
await ApplicationStateModel.SaveSessionStateAsync();
deferral.Complete();
}
You can use Windows.Storage.ApplicationData to save local settings.
Take a look at the Sample SDK app for a running app that saves your settings.

Categories