Image sending app for Windows Phone - c#

I'm developing app for Windows Phone 8.1 which have :
Page with file open picker to take photo from gallery and second Page
to sending that one photo as an e-mail attachment with message.
How i can take this one picked picture and send this with e-mail.?
I tried to look some solutions but so far without any luck.
Any suggestion please?
The code is in regular c# and xaml and I'm using Windows Phone 8.1 in Visual Studio 2015.

You can use this solution to your problem in a single step.
/// <summary>
/// Taking photo from the gallery
/// </summary>
private void SharePhotoClick(object sender, RoutedEventArgs e)
{
PhotoChooserTask ph=new PhotoChooserTask();
ph.Completed += ph_Completed;
ph.Show();
}
/// <summary>
/// Sharing the photo to social media including email
/// </summary>
void ph_Completed(object sender, PhotoResult e)
{
ShareMediaTask smt = new ShareMediaTask();
smt.FilePath = e.OriginalFileName;
smt.Show();
}
Hope this helps!
Note: Please ignore or remove answer if you are developing universal wp application.

I believe in WP8.1 you would require to implement the IContinuationManager which will help you get the image selected by the user.
First you need an event where you open up the Gallery
private void PickAFileButton_Click(object sender, RoutedEventArgs e)
{
...
FileOpenPicker openPicker = new FileOpenPicker();
openPicker.ViewMode = PickerViewMode.Thumbnail;
openPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
openPicker.FileTypeFilter.Add(".jpg");
openPicker.FileTypeFilter.Add(".jpeg");
openPicker.FileTypeFilter.Add(".png");
// Launch file open picker and caller app is suspended
// and may be terminated if required
openPicker.PickSingleFileAndContinue();
}
Once the image is selected then OnActivated() method in app.xaml.cs is called where you need continuation manager to get the data of file selected.
protected async override void OnActivated(IActivatedEventArgs args)
{
base.OnActivated(args);
var continuationManager = new ContinuationManager();
var rootFrame = CreateRootFrame();
await RestoreStatusAsync(args.PreviousExecutionState);
if (rootFrame.Content == null)
{
rootFrame.Navigate(typeof(MainPage));
}
var continuationEventArgs = e as IContinuationActivatedEventArgs;
if (continuationEventArgs != null)
{
Frame scenarioFrame = MainPage.Current.FindName("ScenarioFrame") as Frame;
if (scenarioFrame != null)
{
// Call ContinuationManager to handle continuation activation
continuationManager.Continue(continuationEventArgs, scenarioFrame);
}
}
Window.Current.Activate();
}
Now the continuation manager will handle the activation for you.
case ActivationKind.PickSaveFileContinuation:
var fileSavePickerPage = rootFrame.Content as IFileSavePickerContinuable;
if (fileSavePickerPage != null)
{
fileSavePickerPage.ContinueFileSavePicker(args as FileSavePickerContinuationEventArgs);
}
break;
case ActivationKind.PickFolderContinuation:
var folderPickerPage = rootFrame.Content as IFolderPickerContinuable;
if (folderPickerPage != null)
{
folderPickerPage.ContinueFolderPicker(args as FolderPickerContinuationEventArgs);
}
break;
case ActivationKind.WebAuthenticationBrokerContinuation:
var wabPage = rootFrame.Content as IWebAuthenticationContinuable;
if (wabPage != null)
{
wabPage.ContinueWebAuthentication(args as WebAuthenticationBrokerContinuationEventArgs);
}
break;
}
All the code snippets are available here https://msdn.microsoft.com/en-us/library/windows/apps/xaml/dn631755.aspx
Once this is done you can fetch the data and save it to a file and attach that file to email.
EmailMessage email = new EmailMessage();
email.To.Add(new EmailRecipient("test#abc.com"));
email.Subject = "Test";
var file = await GetFile();
email.Attachments.Add(new EmailAttachment(file.Name, file));
await EmailManager.ShowComposeNewEmailAsync(email);
More details in this link http://developerpublish.com/windows-phone-8-1-and-windows-runtime-apps-how-to-2-send-emails-with-attachment-in-wp-8-1/
Hope this helps!

Related

UWP AutoNext Function

I'm trying to Get a Auto Next method i've tried using a Index Counter but I think I misunderstand how to properly set a list using the FilePicker
The code for the FilePicker is following :
public async void pick_Click_1(object sender, RoutedEventArgs e)
{
List<StorageFile> fileList = new List<StorageFile>();
var fop = new FileOpenPicker();
fop.FileTypeFilter.Add(".mp3");
fop.FileTypeFilter.Add(".mp4");
fop.FileTypeFilter.Add(".avi");
fop.FileTypeFilter.Add(".wmv");
fop.ViewMode = PickerViewMode.List;
pickedFileList = await fop.PickMultipleFilesAsync();
// add the picked files to our existing list
fileList.AddRange(pickedFileList);
foreach (StorageFile file in pickedFileList)
{
Playlist.Items.Add(file);
var stream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
videoMediaElement.SetSource(stream, file.ContentType);
}
videoMediaElement.Play();
The Current method i have for switching tracks|Videos
private async void itemclicked(object sender, ItemClickEventArgs e)
{
var file = e.ClickedItem as StorageFile;
if (file != null)
{
var stream = await file.OpenReadAsync();
videoMediaElement.SetSource(stream, file.ContentType);
}
}
Empty Event im trying to use to do this.
private void Element_MediaEnded(object sender, RoutedEventArgs e)
{
}
I've looked threw all the Microsoft Sample's. Issue Being They use the Mediaplayerelement += Mediaplayer And im using the MediaElement
The Answers Im looking for Can be A Resolution to my problem or assisting me in better understanding how to globally set the source of the mediaplayer using the Current or new list from the picker, Im new to all this and trying to grasp everything better Thank you!
I ended up taking Tousee's advice to seem's he's my mentor at this stage, I used the MediaplayerElement and mediaPLaybacklist's which made life Easier. And almost instantly fixed my problem.

UWP OnShareTargetActivated Windows.System.Launcher.LaunchUriAsync does not work after first run

I would like to open my app after another app choose my app as the target for sharing a web link.
So first I use OnShareTargetActivated to read the weblink and then use LaunchUriAsync to launch my app through a custom scheme I created for it.
protected override async void OnShareTargetActivated(ShareTargetActivatedEventArgs args)
{
ShareOperation shareOperation = args.ShareOperation;
try
{
if (shareOperation.Data.Contains(StandardDataFormats.WebLink))
{
var URL = await shareOperation.Data.GetWebLinkAsync();
var mAloudURI = #"myApp:?URL=" + URL;
// Launch the URI
await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
{
var success = await Windows.System.Launcher.LaunchUriAsync(new Uri(mAloudURI));
});
shareOperation.ReportCompleted();
}
}
catch (Exception exc)
{
var i = 0;
}
}
After that, I use OnActivated to read the link and open my MainPage on the passed link.
protected override void OnActivated(IActivatedEventArgs args)
{
if (args.Kind == ActivationKind.Protocol)
{
ProtocolActivatedEventArgs eventArgs = args as ProtocolActivatedEventArgs;
var url = eventArgs.Uri.PathAndQuery.Substring("?URL=".Length);
Frame rootFrame = Window.Current.Content as Frame;
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame != null)
{
rootFrame.Navigate(typeof(MainPage), url);
}
}
}
When I'm debugging I get the expected behavior when I F10 (step through) the line calling LaunchUriAsync, then OnActivated gets executed and MainPage gets displayed with the URL I wanted...
However if I try to share again, the secondary popup window for my app gets displayed for a while and then it disappears. Non of my break points get hit...
Is this the correct approach?
This looks to me like a very logical way of opening other apps with the content you are sharing to them...

WindowsPhone 8.1 FlashLight

I have Nokia 730 and I want to make FlashLight work on it. But next code crash:
MediaCapture mc = new MediaCapture();
await mc.InitializeAsync();
if (mc.VideoDeviceController.TorchControl.Supported == true)
{
mc.VideoDeviceController.TorchControl.Enabled = true;
mc.VideoDeviceController.TorchControl.PowerPercent = 100; // here is crash
}
Any ideas? For some reasons solutions with older platforms (wp 7, wp8) doesn't works at all.
Fixed it by next code:
private async void Button_Click(object sender, RoutedEventArgs e)
{
// Initialize Media Capture and Settings Objects, mediaCapture declared global outside this method
var mediaCapture = new MediaCapture();
// Grab all available VideoCapture Devices and find rear device (usually has flash)
await mediaCapture.InitializeAsync();
var videoEncodingProperties = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.Vga);
var videoStorageFile = await KnownFolders.VideosLibrary.CreateFileAsync("tempVideo.mp4", CreationCollisionOption.GenerateUniqueName);
await mediaCapture.StartRecordToStorageFileAsync(videoEncodingProperties, videoStorageFile);
await Task.Delay(TimeSpan.FromMilliseconds(500));
mediaCapture.VideoDeviceController.TorchControl.Enabled = true;
}
But for some reason I should wait 500 milliseconds before enable TorchControl. Can someone explain why?
According to this post it could help to try the following:
//to switch OFF flash light
mc.VideoDeviceController.FlashControl.Enabled = false;
//to switch ON flash light
mc.VideoDeviceController.FlashControl.Enabled = true;

How get navigation control from a button?

I know if I used a view controller I can use this:
var scanner = new MobileBarcodeScanner(this.NavigationController);
How do I know what navigation I am using inside of button I need use?
public class BarReaderButtonRenderer : ButtonRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
{
base.OnElementChanged(e);
// I tried this but don't worked
var scanner = new MobileBarcodeScanner(this.NavigationController);
// I tried this but do
var scanner = new MobileBarcodeScanner(this);
Element.Clicked += async(s_, e_) => {
// Setup our button
// Tell our scanner to use the default overlay
scanner.UseCustomOverlay = false;
//We can customize the top and bottom text of the default overlay
scanner.TopText = "Hold camera up to barcode to scan";
scanner.BottomText = "Barcode will automatically scan";
//Start scanning
var result = await scanner.Scan ();
HandleScanResult(result);
};
}
}
I can't use this code inside a button render. Or did someone this before?
The project is a shared application for iOS and Android.
The code for creating the scanner should stay inside the view controller/activity/page. You can still use the custom button and add the code you need to the Clicked event handler.
var myCustomButton = new BarReaderButton();
myCustomButton.Clicked += async(s, e) => {
var scanner = new MobileBarcodeScanner();
scanner.UseCustomOverlay = false;
//Start scanning
var result = await scanner.Scan ();
//Do something with the result
};
If this is Xamarin.Forms you will also have to use platform specific code inside the Page code as the barcode reader requires a Context on Android:
#if __IOS__
var scanner = new MobileBarcodeScanner();
#elif __ANDROID__
var scanner = new MobileBarcodeScanner(Forms.Context);
#endif

saving state between pages when creating a windows 8 app

I've been following the Create your first Windows Store app using C# or Visual Basic tutorials provided by Microsoft but am having some problems saving state when navigating between pages.
Create your first Windows Store app using C# or Visual Basic
Part 3: Navigation, layout, and views
Basically I've noticed that if I navigate from the main page to the photo page select a photo, navigate back to the main page and then go to the photo page again it doesn't remember the photo that was selected. I'm using the following code to navigate to the photo page from the main page.
private void photoPageButton_Click(object sender, RoutedEventArgs e)
{
this.Frame.Navigate(typeof(PhotoPage));
}
In the photo page the loadstate method is
protected async override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)
{
if (pageState != null && pageState.ContainsKey("mruToken"))
{
object value = null;
if (pageState.TryGetValue("mruToken", out value))
{
if (value != null)
{
mruToken = value.ToString();
// Open the file via the token that you stored when adding this file into the MRU list.
Windows.Storage.StorageFile file =
await Windows.Storage.AccessCache.StorageApplicationPermissions.MostRecentlyUsedList.GetFileAsync(mruToken);
if (file != null)
{
// Open a stream for the selected file.
Windows.Storage.Streams.IRandomAccessStream fileStream =
await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
// Set the image source to a bitmap.
Windows.UI.Xaml.Media.Imaging.BitmapImage bitmapImage =
new Windows.UI.Xaml.Media.Imaging.BitmapImage();
bitmapImage.SetSource(fileStream);
displayImage.Source = bitmapImage;
// Set the data context for the page.
this.DataContext = file;
}
}
}
}
}
The photo page save state is
protected override void SaveState(Dictionary<String, Object> pageState)
{
if (!String.IsNullOrEmpty(mruToken))
{
pageState["mruToken"] = mruToken;
}
}
I've noticed that the pagestate is always null when navigated to. Any ideas?
Enable NavigationCacheMode property of the page and add NavigationCacheMode="Enabled"
OR
Enable it by properties panel.
I did this tutorial too and I found one solution to save the state across pages navigation.
First, override the OnNavigatedFrom in order to save the file token into State Frame:
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
var state = SuspensionManager.SessionStateForFrame(this.Frame);
state["mruToken"] = mruToken;
}
Override the OnNavigatedTo in order to load the token from the state:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
var state = SuspensionManager.SessionStateForFrame(this.Frame);
if (state != null && state.ContainsKey("mruToken"))
{
object value = null;
if (state.TryGetValue("mruToken", out value))
{
// the same code as LoadState to retrieve the image
}
}
}
In fact, I wrote another function to retrieve the image so it can be used in both LoadState and OnNavigatedTo methods.
private async void restoreImage(object value)
{
if (value != null)
{
mruToken = value.ToString();
// Open the file via the token that you stored when adding this file into the MRU list.
Windows.Storage.StorageFile file =
await Windows.Storage.AccessCache.StorageApplicationPermissions.MostRecentlyUsedList.GetFileAsync(mruToken);
if (file != null)
{
// Open a stream for the selected file.
Windows.Storage.Streams.IRandomAccessStream fileStream =
await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
// Set the image source to a bitmap.
Windows.UI.Xaml.Media.Imaging.BitmapImage bitmapImage =
new Windows.UI.Xaml.Media.Imaging.BitmapImage();
bitmapImage.SetSource(fileStream);
displayImage.Source = bitmapImage;
// Set the data context for the page.
this.DataContext = file;
}
}
}
The problem is coming from the NavigationHelper OnNavigateTo method
public void OnNavigatedTo(NavigationEventArgs e)
{
var frameState = SuspensionManager.SessionStateForFrame(this.Frame);
this._pageKey = "Page-" + this.Frame.BackStackDepth;
if (e.NavigationMode == NavigationMode.New)
{
// Clear existing state for forward navigation when adding a new page to the
// navigation stack
var nextPageKey = this._pageKey;
int nextPageIndex = this.Frame.BackStackDepth;
while (frameState.Remove(nextPageKey))
{
nextPageIndex++;
nextPageKey = "Page-" + nextPageIndex;
}
// Pass the navigation parameter to the new page
if (this.LoadState != null)
{
this.LoadState(this, new LoadStateEventArgs(e.Parameter, null));
}
}
else
{
// Pass the navigation parameter and preserved page state to the page, using
// the same strategy for loading suspended state and recreating pages discarded
// from cache
if (this.LoadState != null)
{
this.LoadState(this, new LoadStateEventArgs(e.Parameter, (Dictionary<String, Object>)frameState[this._pageKey]));
}
}
}
if (e.NavigationMode == NavigationMode.New) if always true because Frame by default creates a new instance of the Page. See Frame Class Remarks. So The LoadState event handler is always called with a null state parameter
if (this.LoadState != null)
{
this.LoadState(this, new LoadStateEventArgs(e.Parameter, null));
}
Now if you look at the complete code for PhotoPage.xaml very closely you will notice that in the page header there is this NavigationCacheMode="Enabled" that is what makes it PhotoPage works.
There no need for all that code about saving states in the Page. The Frame class does that for you when the Page sets its NavigationCacheMode.

Categories

Resources