Friday 28 June 2013

Upload files Using Drop box API with Android

Hello friends,
Today i am going to post, upload multiple images to drop box from android application.

Drop provide lib for this, you can download from here. its have sample code also for upload one image.

here i have modify code and made one sample for upload multiple image in dropbox using its sdk.

Before implement this in App, you have to create app in dropbox developer like fb and twitter for app keys.




Upload Class:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.widget.Toast;
import com.HB.uploaddbphotos.API_Listener;
import com.HB.uploaddbphotos.UploadPhotos_Activity;
import com.dropbox.client2.DropboxAPI;
import com.dropbox.client2.DropboxAPI.UploadRequest;
import com.dropbox.client2.exception.DropboxException;
import com.dropbox.client2.exception.DropboxFileSizeException;
import com.dropbox.client2.exception.DropboxIOException;
import com.dropbox.client2.exception.DropboxParseException;
import com.dropbox.client2.exception.DropboxPartialFileException;
import com.dropbox.client2.exception.DropboxServerException;
import com.dropbox.client2.exception.DropboxUnlinkedException;

public class Upload extends AsyncTask<Void, Long, Boolean>
{

       private DropboxAPI<?> mApi;
       private String mPath;

       private UploadRequest mRequest;
       private Context mContext;
       private ProgressDialog mDialog;

       private String mErrorMsg;

       //new class variables:
       int mFilesUploaded;
       private File[] mFilesToUpload;
       int mCurrentFileIndex;
       int totalBytes = 0;

       API_Listener api_Listener;
       UploadPhotos_Activity uploadPhotos_Activity;
       private int requestNumber;

       public Upload(int request_num,UploadPhotos_Activity activity, DropboxAPI<?> api, String dropboxPath, File[] filesToUpload)
       {
              // We set the context this way so we don't accidentally leak activities
              mContext = activity;      
              api_Listener=activity;
              mApi = api;
              mPath = dropboxPath;
              requestNumber=request_num;

              //set number of files uploaded to zero.
              mFilesUploaded = 0;
              mFilesToUpload = filesToUpload;
              mCurrentFileIndex = 0;
             
              mDialog = new ProgressDialog(mContext);
              mDialog.setMax(mFilesToUpload.length);  
              mDialog.setMessage("Uploading...");
              mDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
              mDialog.setProgress(0); 
              mDialog.setCancelable(false);
              mDialog.show();
       }


       @Override
       protected void onPreExecute()
       {
              super.onPreExecute();

       }
       @Override
       protected Boolean doInBackground(Void... params)
       {
              FileInputStream fis;
              try
              {                         

                     for (int i = 0; i < mFilesToUpload.length; i++)
                     {
                           mCurrentFileIndex = i;
                           File file = mFilesToUpload[i];

                           publishProgress(Long.parseLong(""+i));

                           // By creating a request, we get a handle to the putFile
                           // operation,
                           // so we can cancel it later if we want to
                           fis = new FileInputStream(file);                      
                           String path = mPath + file.getName();
                           mRequest = mApi.putFileOverwriteRequest(path, fis,file.length(),null);                  
                          

                           mRequest.upload();

                           if (!isCancelled())
                           {
                                  mFilesUploaded++;
                           }
                           else
                           {
                                  return false;
                           }
                     }
                     return true;
              } catch (DropboxUnlinkedException e) {
                     // This session wasn't authenticated properly or user unlinked
                     mErrorMsg = "This app wasn't authenticated properly.";
              } catch (DropboxFileSizeException e) {
                     // File size too big to upload via the API
                     mErrorMsg = "This file is too big to upload";
              } catch (DropboxPartialFileException e) {
                     // We canceled the operation
                     mErrorMsg = "Upload canceled";
              } catch (DropboxServerException e) {
                     // Server-side exception. These are examples of what could happen,
                     // but we don't do anything special with them here.
                     if (e.error == DropboxServerException._401_UNAUTHORIZED) {
                           // Unauthorized, so we should unlink them. You may want to
                           // automatically log the user out in this case.
                     } else if (e.error == DropboxServerException._403_FORBIDDEN) {
                           // Not allowed to access this
                     } else if (e.error == DropboxServerException._404_NOT_FOUND) {
                           // path not found (or if it was the thumbnail, can't be
                           // thumbnailed)
                     } else if (e.error == DropboxServerException._507_INSUFFICIENT_STORAGE) {
                           // user is over quota
                     } else {
                           // Something else
                     }
                     // This gets the Dropbox error, translated into the user's language
                     mErrorMsg = e.body.userError;
                     if (mErrorMsg == null) {
                           mErrorMsg = e.body.error;
                     }
              } catch (DropboxIOException e) {
                     // Happens all the time, probably want to retry automatically.
                     mErrorMsg = "Network error.  Try again.";
              } catch (DropboxParseException e) {
                     // Probably due to Dropbox server restarting, should retry
                     mErrorMsg = "Dropbox error.  Try again.";
              } catch (DropboxException e) {
                     // Unknown error
                     mErrorMsg = "Unknown error.  Try again.";
              } catch (FileNotFoundException e) {
              }

              return false;
       }

       @Override
       protected void onProgressUpdate(Long... progress)
       {     
              mDialog.setProgress(Integer.parseInt(""+progress[0]));       
              super.onProgressUpdate(progress);
       }

       @Override
       protected void onPostExecute(Boolean result)
       {
              mDialog.dismiss();

              if (result)
              {
                     api_Listener.onSuccess(requestNumber, result);               
              }
              else
              {
                     showToast(mErrorMsg);
              }
       }
       private void showToast(String msg)
       {
              Toast error = Toast.makeText(mContext, msg, Toast.LENGTH_LONG);
              error.show();
       }

}

Upload Photos Activity:
import java.io.File;
import java.util.ArrayList;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.dropbox.android.sample.Upload;
import com.dropbox.client2.DropboxAPI;
import com.dropbox.client2.android.AndroidAuthSession;
import com.dropbox.client2.android.AuthActivity;
import com.dropbox.client2.session.AccessTokenPair;
import com.dropbox.client2.session.AppKeyPair;
import com.dropbox.client2.session.Session.AccessType;
import com.dropbox.client2.session.TokenPair;

public class UploadPhotos_Activity extends Activity implements API_Listener
{
      
       File[] listFile;
       ArrayList<String> f = new ArrayList<String>();// list of file paths

       // Replace this with your app key and secret assigned by Dropbox.
       // Note that this is a really insecure way to do this, and you shouldn't
       // ship code which contains your key & secret in such an obvious way.
       // Obfuscation is good.
       final static private String APP_KEY = "App key here...";
       final static private String APP_SECRET = "App secret key";

       // If you'd like to change the access type to the full Dropbox instead of
       // an app folder, change this value.
       final static private AccessType ACCESS_TYPE = AccessType.APP_FOLDER;

       // You don't need to change these, leave them alone.
       final static private String ACCOUNT_PREFS_NAME = "prefs";
       final static private String ACCESS_KEY_NAME = "ACCESS_KEY";
       final static private String ACCESS_SECRET_NAME = "ACCESS_SECRET";
       DropboxAPI<AndroidAuthSession> mApi;
       private boolean mLoggedIn;

       // Android widgets   
       private Button btn_linkDropbox;
       private final String PHOTO_DIR = "/Photos/";
      
       int count=0; 
      
       @Override
       public void onSuccess(int requestnumber, Object obj)
       {
              try
              {
                     if(requestnumber == Constants.UploadPhotos_Code)
                     {
                           boolean sucess=(Boolean) obj;
                           if(sucess)
                           {
                                  Toast.makeText(UploadPhotos_Activity.this"Photos uploaded successfully", Toast.LENGTH_LONG).show();
                                  Intent i=newIntent(UploadPhotos_Activity.this,UploadPhotos_Activity.class);
                                  startActivity(i);
                                  finish();
                           }
                     }
              }
              catch (Exception e)
              {
                     e.printStackTrace();
              }
             
       }
       @Override
       public void onFail(String errormessage)
       {
             
             
       }

      
       @Override
       protected void onCreate(Bundle savedInstanceState)
       {
             
              super.onCreate(savedInstanceState);

              // We create a new AuthSession so that we can use the Dropbox API.
              AndroidAuthSession session = buildSession();
              mApi = new DropboxAPI<AndroidAuthSession>(session);

              setContentView(R.layout.main);          

              checkAppKeySetup();    

              // Display the proper UI state if logged in or not
              setLoggedIn(mApi.getSession().isLinked());
              getFromSdcard();

       }
       public void getFromSdcard()
       {

              File file = new File(Environment.getExternalStoragePublicDirectory
                           (Environment.DIRECTORY_PICTURES),  Constants.PhotoSaveDirectory);

              if (file.isDirectory())
              {
                     listFile = file.listFiles();

                     for (int i = 0; i < listFile.length; i++)
                     {

                           f.add(listFile[i].getAbsolutePath());

                     }
              }
       }

       public void BTB_ClickEvent(View v)
       {
              int id=v.getId();
              if(id==R.id.btn_linkDropbox)
              {
                     // This logs you out if you're logged in, or vice versa
                     if (mLoggedIn)
                     {
                           logOut();
                     }
                     else
                     {
                           // Start the remote authentication
                          mApi.getSession().startAuthentication(UploadPhotos_Activity.this);
                     }

              }
              else if (id==R.id.btn_upload)
              {
                     if(mLoggedIn)
                     {
                           if (listFile!=null&&listFile.length>0)
                           {                                
                                  Upload upload = newUpload(Constants.UploadPhotos_Code,UploadPhotos_Activity.thismApiPHOTO_DIR,listFile);
                                  upload.execute();
                           }
                           else
                           {
                                  Toast.makeText(UploadPhotos_Activity.this"No photos available for upload.",Toast.LENGTH_LONG).show();
                           }
                     }
                     else
                     {
                           Toast.makeText(UploadPhotos_Activity.this"This app wasn't authenticated properly.Please link with dropbox to upload photos",Toast.LENGTH_LONG).show();
                     }
                    
              }
       }     

       @Override
       protected void onResume()
       {
              super.onResume();
              AndroidAuthSession session = mApi.getSession();

              // The next part must be inserted in the onResume() method of the
              // activity from which session.startAuthentication() was called, so
              // that Dropbox authentication completes properly.
              if (session.authenticationSuccessful())
              {
                     try {
                           // Mandatory call to complete the auth
                           session.finishAuthentication();

                           // Store it locally in our app for later use
                           TokenPair tokens = session.getAccessTokenPair();
                           storeKeys(tokens.key, tokens.secret);
                           setLoggedIn(true);
                     } catch (IllegalStateException e) {
                           showToast("Couldn't authenticate with Dropbox:" + e.getLocalizedMessage());
                          
                     }
              }
       }

       // This is what gets called on finishing a media piece to import


       private void logOut()
       {
              // Remove credentials from the session
              mApi.getSession().unlink();

              // Clear our stored keys
              clearKeys();
              // Change UI state to display logged out version
              setLoggedIn(false);
       }

       /**
        * Convenience function to change UI state based on being logged in
        */
       private void setLoggedIn(boolean loggedIn)
       {
              btn_linkDropbox=(Button) findViewById(R.id.btn_linkDropbox);

              mLoggedIn = loggedIn;     
              if (loggedIn)
              {
                     btn_linkDropbox.setText("Unlink from Dropbox");

              }
              else
              {
                     btn_linkDropbox.setText("Link with Dropbox");         

              }
       }

       private void checkAppKeySetup()
       {
              // Check to make sure that we have a valid app key
              if (APP_KEY.startsWith("CHANGE") ||
                           APP_SECRET.startsWith("CHANGE"))
              {
                     showToast("You must apply for an app key and secret from developers.dropbox.com, and add them to the DBRoulette ap before trying it.");
                     finish();
                     return;
              }

              // Check if the app has set up its manifest properly.
              Intent testIntent = new Intent(Intent.ACTION_VIEW);
              String scheme = "db-" + APP_KEY;
              String uri = scheme + "://" + AuthActivity.AUTH_VERSION + "/test";
              testIntent.setData(Uri.parse(uri));
              PackageManager pm = getPackageManager();
              if (0 == pm.queryIntentActivities(testIntent, 0).size()) {
                     showToast("URL scheme in your app's " +
                                  "manifest is not set up correctly. You should have a " +
                                  "com.dropbox.client2.android.AuthActivity with the " +
                                  "scheme: " + scheme);
                     finish();
              }
       }

       private void showToast(String msg) {
              Toast error = Toast.makeText(this, msg, Toast.LENGTH_LONG);
              error.show();
       }

       /**
        * Shows keeping the access keys returned from Trusted Authenticator in a local
        * store, rather than storing user name & password, and re-authenticating each
        * time (which is not to be done, ever).
        *
        * @return Array of [access_key, access_secret], or null if none stored
        */
       private String[] getKeys() {
              SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME, 0);
              String key = prefs.getString(ACCESS_KEY_NAMEnull);
              String secret = prefs.getString(ACCESS_SECRET_NAMEnull);
              if (key != null && secret != null) {
                     String[] ret = new String[2];
                     ret[0] = key;
                     ret[1] = secret;
                     return ret;
              } else {
                     return null;
              }
       }

       /**
        * Shows keeping the access keys returned from Trusted Authenticator in a local
        * store, rather than storing user name & password, and re-authenticating each
        * time (which is not to be done, ever).
        */
       private void storeKeys(String key, String secret) {
              // Save the access key for later
              SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME, 0);
              Editor edit = prefs.edit();
              edit.putString(ACCESS_KEY_NAME, key);
              edit.putString(ACCESS_SECRET_NAME, secret);
              edit.commit();
       }

       private void clearKeys() {
              SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME, 0);
              Editor edit = prefs.edit();
              edit.clear();
              edit.commit();
       }

       private AndroidAuthSession buildSession() {
              AppKeyPair appKeyPair = new AppKeyPair(APP_KEYAPP_SECRET);
              AndroidAuthSession session;

              String[] stored = getKeys();
              if (stored != null) {
                     AccessTokenPair accessToken = new AccessTokenPair(stored[0], stored[1]);
                     session = new AndroidAuthSession(appKeyPair, ACCESS_TYPE, accessToken);
              } else {
                     session = new AndroidAuthSession(appKeyPair, ACCESS_TYPE);
              }

              return session;
       }     
      
}


Listener for response API_Listener.java:
public interface API_Listener
{
       public void onSuccess(int requestnumber, Object obj); 
       public void onFail(String errormessage);
}

Constants:
public class Constants
{
       public static int UploadPhotos_Code=3000;      
       public static String PhotoSaveDirectory="HBphotos";
}

AndroidManifest.xml
here is the activity we need to in AndroidManifest.xml file.
        <activity
            android:name="com.dropbox.client2.android.AuthActivity"
            android:configChanges="orientation|keyboard"
            android:launchMode="singleTask" >
            <intent-filter>

                <!-- Change this to be db- followed by your app key -->
                <data android:scheme="db-youappkeyhere" />

                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.BROWSABLE" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>

i will be happy if you will provide your feedback or follow this blog. Any suggestion and help will be appreciated.
Thank you :)