Namespaces

Variants
Actions

Please note that as of October 24, 2014, the Nokia Developer Wiki will no longer be accepting user contributions, including new entries, edits and comments, as we begin transitioning to our new home, in the Windows Phone Development Wiki. We plan to move over the majority of the existing entries over the next few weeks. Thanks for all your past and future contributions.

Revision as of 10:52, 6 September 2012 by jupaavola (Talk | contribs)

Dropbox with Windows Phone

From Wiki
Jump to: navigation, search

This article explains how to connect Windows Phone to Dropbox cloud service by using Sharpbox

WP Metro Icon File.png
WP Metro Icon Web.png
SignpostIcon XAML 40.png
WP Metro Icon WP8.png
SignpostIcon WP7 70px.png
Article Metadata
CompatibilityArticle
Created: jupaavola (31 Aug 2012)
Last edited: jupaavola (06 Sep 2012)

Contents

Introduction

Some user may want to connect other cloud services than SkyDrive which is offered by Microsoft. By using Open Source project called Sharpbox, you can access to Dropbox clouds. At the time of writing this article, it is still not possible to access other clouds like CloudMe in Windows Phone although those others works with desktops.

Summary

Required software

Go to Sharpbox website: http://sharpbox.codeplex.com/

Download SharpBox release 1.1 SR2 or older. Newer release 1.2 does not work so well with Windows Phone and have few bugs when logging and authenticating to Dropbox service.

Extract downloaded zip file and add two DLL, AppLimit.CloudComputing.SharpBox.dll and Newtonsoft.Json.Silverlight.dll, files from sl3-wp folder as reference to your project.

Sharpbox prerequisities

Sharpbox needs valid Dropbox application key and secret. These can be made in Dropbox website, developers section where you create own application. For testing and developing, you don't need to apply for production keys.

Dropbox developers: https://www.dropbox.com/developers

Using Sharpbox

Sharpbox library has synchronized and asynchronized functions for many operations. For desktop usage both are fine but in Windows Phone, operating system and it's frameworks has their own limitations. All of the synchronized calls will block running UI thread and therefore the whole application. The only way to get things working is to use asynchronous functions. Some needed functions still lack of asynchronous versions but it is possible to use these by implementing own async versions to own application.

Sharpbox does not run in UI thread

Note that used functions from Sharpbox are asynchronous and those are not run in UI thread where your application is running. Still it is possible to call your application functions or change member variables from callback functions by using dispatcher.

Example function CallbackFunction is asynchronous callback function. This snippet shows how to use dispatcher to call parseFilesAndDirectories function what is normail private function in application thread.

void CallbackFunction(IAsyncResult result)
{
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
if (fs != null)
{
parseFilesAndDirectories(fs);
}
});
}

Logging to Dropbox

This is pretty easy, create credentials and configuration object. Then call BeginOpenRequest and wait for callback.

        public void ConnectCloud(string username, string password)
{
DropBoxCredentials creds = new DropBoxCredentials();
creds.ConsumerSecret = APP_SECRET;
creds.ConsumerKey = APP_KEY;
creds.UserName = username;
creds.Password = password;
 
m_dropBox.BeginOpenRequest(LoginCallback, mCloudConfig, creds);
}

And the callback function for open request. Token of Dropbox connection is extracted from asynchronous functions result. This token also determines did connection succeed; if value is null, connection failed and in other values it succeeded. Without having token value, cannot continue because Sharpbox library does not know is service there.

        void LoginCallback(IAsyncResult result)
{
ICloudStorageAccessToken token = m_dropBox.EndOpenRequest(result);
if (token != null)
{
m_dropBox.BeginGetRootRequest(RootCallback);
}
else if (m_dropBox.IsOpened)
{
m_dropBox.BeginGetRootRequest(RootCallback);
}
}

Get Dropbox file listing

After successful connection, we can proceed to reading files from Dropbox. As seen in LoginCallback, RootCallback function is callback for BeginGetRootRequest asynchronous function.Before reading any file from Dropbox, you need to know root where start. After having root, it's possible to read files from anywhere. So reading root folder is important only in the beginning. And from reading root callback, again jump to another async callback function.

        private void RootCallback(IAsyncResult result)
{
ICloudDirectoryEntry root = m_dropBox.EndGetRootRequest(result);
if (root != null)
{
m_dropBox.BeginGetChildsRequest(ChildCallback, root);
}
}

After having child objects of root, any file or dir in topmost level, start parsing results.

        private void ChildCallback(IAsyncResult result)
{
 
List<ICloudFileSystemEntry> fs = m_dropBox.EndGetChildsRequest(result);
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
if (fs != null)
{
parseFilesAndDirectories(fs);
while (m_directories.Count > 0)
{
ICloudDirectoryEntry e = m_directories[0];
m_directories.RemoveAt(0);
m_dropBox.BeginGetChildsRequest(ChildCallback, e);
}
}
});
}

And how to loop results list and populate file list. Example code looks only image files which are ending to JPG.

        private void parseFilesAndDirectories(List<ICloudFileSystemEntry> direntry)
{
foreach (ICloudFileSystemEntry entry in direntry)
{
System.Diagnostics.Debug.WriteLine("entry: " + entry.Name);
if (entry is ICloudDirectoryEntry)
{
m_directories.Add((ICloudDirectoryEntry)entry);
}
 
if (entry is ICloudFileSystemEntry && entry.Name.EndsWith(".jpg", StringComparison.CurrentCultureIgnoreCase))
{
Files.Add(new CloudItem() { Name = entry.Name, Entry = entry });
}
}
}

Downloading files

Although Sharpbox has synchronous function to get file system objects from Dropbox, those won't work in Windows phone because again, synchronous functions will block UI-thread and therefore whole application. To work things out, implement asynchronous wrapper to synchronous function. This wrapping code will run synchronous function in separate thread.

Implement helper functions, GetFileUri is entry point to start work. This function constructs request and sets callback function to thread, what is sent to ThreadPool.

        public void GetFileUri(AsyncCallback callback, ICloudFileSystemEntry entry)
{
BackgroundRequest request = new BackgroundRequest();
request.callback = callback;
request.result = new AsyncResultEx(request);
request.fileEntry = entry;
ThreadPool.QueueUserWorkItem(GetFileUriCallback, request);
}

After awhile, callback function will be fired and we can try to get Dropbox file object URL. Note that this is not in your application (UI-thread) anymore. Use dispatcher if you need communicating to your application.

        private void GetFileUriCallback(object state)
{
BackgroundRequest req = state as BackgroundRequest;
 
try
{
req.OperationResult = m_dropBox.GetFileSystemObjectUrl(req.fileEntry.Name, req.fileEntry.Parent);
}
catch (Exception e)
{
var openRequest = req.result.AsyncState as BackgroundRequest;
openRequest.OperationResult = null;
openRequest.errorReason = e;
}
 
req.callback(req.result);
}

Also end function is needed, this actually return result of thread.

        public Uri EndGetFileUri(IAsyncResult result)
{
BackgroundRequest req = result.AsyncState as BackgroundRequest;
return req.OperationResult as Uri;
}

Now GetFileUri can be used to get file URL.

        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
CloudHandler ch = Application.Current.Resources["CloudHandler"] as CloudHandler;
if (ch != null)
{
imageProgress.IsIndeterminate = true;
ch.GetFileUri(UrlCallback, ch.CurrentItem.Entry);
}
}

Almost there, only one callback function still needed. Here will be more handling to URL what you get. Example code gets URL and then downloads image file, later shows it.

        void UrlCallback(IAsyncResult result)
{
Uri fileUri = result as Uri;
 
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
CloudHandler ch = Application.Current.Resources["CloudHandler"] as CloudHandler;
fileUri = ch.EndGetFileUri(result);
BitmapImage bi = new BitmapImage();
bi.DownloadProgress += new EventHandler<DownloadProgressEventArgs>(bi_DownloadProgress);
bi.UriSource = fileUri;
currentImage.Source = bi;
});
}
978 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×