5128a691c879db0af46c7c86c88748a98dd67202
[pub/Android/ownCloud.git] / src / com / owncloud / android / ui / activity / Uploader.java
1 /**
2 * ownCloud Android client application
3 *
4 * @author Bartek Przybylski
5 * Copyright (C) 2012 Bartek Przybylski
6 * Copyright (C) 2015 ownCloud Inc.
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2,
10 * as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22 package com.owncloud.android.ui.activity;
23
24 import java.io.File;
25 import java.util.ArrayList;
26 import java.util.HashMap;
27 import java.util.LinkedList;
28 import java.util.List;
29 import java.util.Stack;
30 import java.util.Vector;
31
32
33 import android.accounts.Account;
34 import android.accounts.AccountManager;
35 import android.app.AlertDialog;
36 import android.app.AlertDialog.Builder;
37 import android.app.Dialog;
38 import android.app.ProgressDialog;
39 import android.content.Context;
40 import android.content.DialogInterface;
41 import android.content.DialogInterface.OnCancelListener;
42 import android.content.DialogInterface.OnClickListener;
43 import android.content.Intent;
44 import android.content.SharedPreferences;
45 import android.content.res.Resources.NotFoundException;
46 import android.database.Cursor;
47 import android.net.Uri;
48 import android.os.Bundle;
49 import android.os.Parcelable;
50 import android.preference.PreferenceManager;
51 import android.provider.MediaStore;
52 import android.provider.MediaStore.Audio;
53 import android.provider.MediaStore.Images;
54 import android.provider.MediaStore.Video;
55 import android.support.v4.app.Fragment;
56 import android.support.v4.app.FragmentManager;
57 import android.support.v4.app.FragmentTransaction;
58 import android.view.View;
59 import android.widget.AdapterView;
60 import android.widget.AdapterView.OnItemClickListener;
61 import android.widget.Button;
62 import android.widget.EditText;
63 import android.widget.ListView;
64 import android.widget.SimpleAdapter;
65 import android.widget.Toast;
66
67 import com.actionbarsherlock.app.ActionBar;
68 import com.actionbarsherlock.view.MenuItem;
69 import com.owncloud.android.MainApp;
70 import com.owncloud.android.R;
71 import com.owncloud.android.authentication.AccountAuthenticator;
72 import com.owncloud.android.datamodel.OCFile;
73 import com.owncloud.android.files.services.FileUploader;
74 import com.owncloud.android.lib.common.operations.RemoteOperation;
75 import com.owncloud.android.lib.common.operations.RemoteOperationResult;
76 import com.owncloud.android.lib.common.utils.Log_OC;
77 import com.owncloud.android.operations.CreateFolderOperation;
78 import com.owncloud.android.ui.dialog.CreateFolderDialogFragment;
79 import com.owncloud.android.ui.dialog.LoadingDialog;
80 import com.owncloud.android.utils.CopyTmpFileAsyncTask;
81 import com.owncloud.android.utils.DisplayUtils;
82 import com.owncloud.android.utils.ErrorMessageAdapter;
83
84
85 /**
86 * This can be used to upload things to an ownCloud instance.
87 */
88 public class Uploader extends FileActivity
89 implements OnItemClickListener, android.view.View.OnClickListener,
90 CopyTmpFileAsyncTask.OnCopyTmpFileTaskListener {
91
92 private static final String TAG = Uploader.class.getSimpleName();
93
94 private AccountManager mAccountManager;
95 private Stack<String> mParents;
96 private ArrayList<Parcelable> mStreamsToUpload;
97 private boolean mCreateDir;
98 private String mUploadPath;
99 private OCFile mFile;
100 private boolean mAccountSelected;
101 private boolean mAccountSelectionShowing;
102
103 private ArrayList<String> mRemoteCacheData;
104 private int mNumCacheFile;
105
106 private final static int DIALOG_NO_ACCOUNT = 0;
107 private final static int DIALOG_WAITING = 1;
108 private final static int DIALOG_NO_STREAM = 2;
109 private final static int DIALOG_MULTIPLE_ACCOUNT = 3;
110
111 private final static int REQUEST_CODE_SETUP_ACCOUNT = 0;
112
113 private final static String KEY_PARENTS = "PARENTS";
114 private final static String KEY_FILE = "FILE";
115 private final static String KEY_ACCOUNT_SELECTED = "ACCOUNT_SELECTED";
116 private final static String KEY_ACCOUNT_SELECTION_SHOWING = "ACCOUNT_SELECTION_SHOWING";
117 private final static String KEY_NUM_CACHE_FILE = "NUM_CACHE_FILE";
118 private final static String KEY_REMOTE_CACHE_DATA = "REMOTE_CACHE_DATA";
119
120 private static final String DIALOG_WAIT_COPY_FILE = "DIALOG_WAIT_COPY_FILE";
121
122 @Override
123 protected void onCreate(Bundle savedInstanceState) {
124 prepareStreamsToUpload();
125
126 if (savedInstanceState == null) {
127 mParents = new Stack<String>();
128 mAccountSelected = false;
129 mAccountSelectionShowing = false;
130 mNumCacheFile = 0;
131
132 // ArrayList for files with path in private storage
133 mRemoteCacheData = new ArrayList<String>();
134 } else {
135 mParents = (Stack<String>) savedInstanceState.getSerializable(KEY_PARENTS);
136 mFile = savedInstanceState.getParcelable(KEY_FILE);
137 mAccountSelected = savedInstanceState.getBoolean(KEY_ACCOUNT_SELECTED);
138 mAccountSelectionShowing = savedInstanceState.getBoolean(KEY_ACCOUNT_SELECTION_SHOWING);
139 mNumCacheFile = savedInstanceState.getInt(KEY_NUM_CACHE_FILE);
140 mRemoteCacheData = savedInstanceState.getStringArrayList(KEY_REMOTE_CACHE_DATA);
141 }
142
143 super.onCreate(savedInstanceState);
144
145 if (mAccountSelected) {
146 setAccount((Account) savedInstanceState.getParcelable(FileActivity.EXTRA_ACCOUNT));
147 }
148
149
150 ActionBar actionBar = getSupportActionBar();
151 actionBar.setIcon(DisplayUtils.getSeasonalIconId());
152
153 }
154
155 @Override
156 protected void setAccount(Account account, boolean savedAccount) {
157 if (somethingToUpload()) {
158 mAccountManager = (AccountManager) getSystemService(Context.ACCOUNT_SERVICE);
159 Account[] accounts = mAccountManager.getAccountsByType(MainApp.getAccountType());
160 if (accounts.length == 0) {
161 Log_OC.i(TAG, "No ownCloud account is available");
162 showDialog(DIALOG_NO_ACCOUNT);
163 } else if (accounts.length > 1 && !mAccountSelected && !mAccountSelectionShowing) {
164 Log_OC.i(TAG, "More than one ownCloud is available");
165 showDialog(DIALOG_MULTIPLE_ACCOUNT);
166 mAccountSelectionShowing = true;
167 } else {
168 if (!savedAccount) {
169 setAccount(accounts[0]);
170 }
171 }
172
173 } else {
174 showDialog(DIALOG_NO_STREAM);
175 }
176
177 super.setAccount(account, savedAccount);
178 }
179
180 @Override
181 protected void onAccountSet(boolean stateWasRecovered) {
182 super.onAccountSet(mAccountWasRestored);
183 initTargetFolder();
184 populateDirectoryList();
185 }
186
187 @Override
188 protected void onSaveInstanceState(Bundle outState) {
189 Log_OC.d(TAG, "onSaveInstanceState() start");
190 super.onSaveInstanceState(outState);
191 outState.putSerializable(KEY_PARENTS, mParents);
192 //outState.putParcelable(KEY_ACCOUNT, mAccount);
193 outState.putParcelable(KEY_FILE, mFile);
194 outState.putBoolean(KEY_ACCOUNT_SELECTED, mAccountSelected);
195 outState.putBoolean(KEY_ACCOUNT_SELECTION_SHOWING, mAccountSelectionShowing);
196 outState.putInt(KEY_NUM_CACHE_FILE, mNumCacheFile);
197 outState.putStringArrayList(KEY_REMOTE_CACHE_DATA, mRemoteCacheData);
198 outState.putParcelable(FileActivity.EXTRA_ACCOUNT, getAccount());
199
200 Log_OC.d(TAG, "onSaveInstanceState() end");
201 }
202
203 @Override
204 protected Dialog onCreateDialog(final int id) {
205 final AlertDialog.Builder builder = new Builder(this);
206 switch (id) {
207 case DIALOG_WAITING:
208 ProgressDialog pDialog = new ProgressDialog(this);
209 pDialog.setIndeterminate(false);
210 pDialog.setCancelable(false);
211 pDialog.setMessage(getResources().getString(R.string.uploader_info_uploading));
212 return pDialog;
213 case DIALOG_NO_ACCOUNT:
214 builder.setIcon(android.R.drawable.ic_dialog_alert);
215 builder.setTitle(R.string.uploader_wrn_no_account_title);
216 builder.setMessage(String.format(
217 getString(R.string.uploader_wrn_no_account_text), getString(R.string.app_name)));
218 builder.setCancelable(false);
219 builder.setPositiveButton(R.string.uploader_wrn_no_account_setup_btn_text, new OnClickListener() {
220 @Override
221 public void onClick(DialogInterface dialog, int which) {
222 if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.ECLAIR_MR1) {
223 // using string value since in API7 this
224 // constatn is not defined
225 // in API7 < this constatant is defined in
226 // Settings.ADD_ACCOUNT_SETTINGS
227 // and Settings.EXTRA_AUTHORITIES
228 Intent intent = new Intent(android.provider.Settings.ACTION_ADD_ACCOUNT);
229 intent.putExtra("authorities", new String[] { MainApp.getAuthTokenType() });
230 startActivityForResult(intent, REQUEST_CODE_SETUP_ACCOUNT);
231 } else {
232 // since in API7 there is no direct call for
233 // account setup, so we need to
234 // show our own AccountSetupAcricity, get
235 // desired results and setup
236 // everything for ourself
237 Intent intent = new Intent(getBaseContext(), AccountAuthenticator.class);
238 startActivityForResult(intent, REQUEST_CODE_SETUP_ACCOUNT);
239 }
240 }
241 });
242 builder.setNegativeButton(R.string.uploader_wrn_no_account_quit_btn_text, new OnClickListener() {
243 @Override
244 public void onClick(DialogInterface dialog, int which) {
245 finish();
246 }
247 });
248 return builder.create();
249 case DIALOG_MULTIPLE_ACCOUNT:
250 CharSequence ac[] = new CharSequence[
251 mAccountManager.getAccountsByType(MainApp.getAccountType()).length];
252 for (int i = 0; i < ac.length; ++i) {
253 ac[i] = DisplayUtils.convertIdn(
254 mAccountManager.getAccountsByType(MainApp.getAccountType())[i].name, false);
255 }
256 builder.setTitle(R.string.common_choose_account);
257 builder.setItems(ac, new OnClickListener() {
258 @Override
259 public void onClick(DialogInterface dialog, int which) {
260 setAccount(mAccountManager.getAccountsByType(MainApp.getAccountType())[which]);
261 onAccountSet(mAccountWasRestored);
262 dialog.dismiss();
263 mAccountSelected = true;
264 mAccountSelectionShowing = false;
265 }
266 });
267 builder.setCancelable(true);
268 builder.setOnCancelListener(new OnCancelListener() {
269 @Override
270 public void onCancel(DialogInterface dialog) {
271 mAccountSelectionShowing = false;
272 dialog.cancel();
273 finish();
274 }
275 });
276 return builder.create();
277 case DIALOG_NO_STREAM:
278 builder.setIcon(android.R.drawable.ic_dialog_alert);
279 builder.setTitle(R.string.uploader_wrn_no_content_title);
280 builder.setMessage(R.string.uploader_wrn_no_content_text);
281 builder.setCancelable(false);
282 builder.setNegativeButton(R.string.common_cancel, new OnClickListener() {
283 @Override
284 public void onClick(DialogInterface dialog, int which) {
285 finish();
286 }
287 });
288 return builder.create();
289 default:
290 throw new IllegalArgumentException("Unknown dialog id: " + id);
291 }
292 }
293
294 class a implements OnClickListener {
295 String mPath;
296 EditText mDirname;
297
298 public a(String path, EditText dirname) {
299 mPath = path;
300 mDirname = dirname;
301 }
302
303 @Override
304 public void onClick(DialogInterface dialog, int which) {
305 Uploader.this.mUploadPath = mPath + mDirname.getText().toString();
306 Uploader.this.mCreateDir = true;
307 uploadFiles();
308 }
309 }
310
311 @Override
312 public void onBackPressed() {
313
314 if (mParents.size() <= 1) {
315 super.onBackPressed();
316 return;
317 } else {
318 mParents.pop();
319 populateDirectoryList();
320 }
321 }
322
323 @Override
324 public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
325 // click on folder in the list
326 Log_OC.d(TAG, "on item click");
327 Vector<OCFile> tmpfiles = getStorageManager().getFolderContent(mFile);
328 if (tmpfiles.size() <= 0) return;
329 // filter on dirtype
330 Vector<OCFile> files = new Vector<OCFile>();
331 for (OCFile f : tmpfiles)
332 if (f.isFolder())
333 files.add(f);
334 if (files.size() < position) {
335 throw new IndexOutOfBoundsException("Incorrect item selected");
336 }
337 mParents.push(files.get(position).getFileName());
338 populateDirectoryList();
339 }
340
341 @Override
342 public void onClick(View v) {
343 // click on button
344 switch (v.getId()) {
345 case R.id.uploader_choose_folder:
346 mUploadPath = ""; // first element in mParents is root dir, represented by "";
347 // init mUploadPath with "/" results in a "//" prefix
348 for (String p : mParents)
349 mUploadPath += p + OCFile.PATH_SEPARATOR;
350 Log_OC.d(TAG, "Uploading file to dir " + mUploadPath);
351
352 uploadFiles();
353
354 break;
355
356 case R.id.uploader_new_folder:
357 CreateFolderDialogFragment dialog = CreateFolderDialogFragment.newInstance(mFile);
358 dialog.show(getSupportFragmentManager(), "createdirdialog");
359 break;
360
361
362 default:
363 throw new IllegalArgumentException("Wrong element clicked");
364 }
365 }
366
367 @Override
368 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
369 super.onActivityResult(requestCode, resultCode, data);
370 Log_OC.i(TAG, "result received. req: " + requestCode + " res: " + resultCode);
371 if (requestCode == REQUEST_CODE_SETUP_ACCOUNT) {
372 dismissDialog(DIALOG_NO_ACCOUNT);
373 if (resultCode == RESULT_CANCELED) {
374 finish();
375 }
376 Account[] accounts = mAccountManager.getAccountsByType(MainApp.getAuthTokenType());
377 if (accounts.length == 0) {
378 showDialog(DIALOG_NO_ACCOUNT);
379 } else {
380 // there is no need for checking for is there more then one
381 // account at this point
382 // since account setup can set only one account at time
383 setAccount(accounts[0]);
384 populateDirectoryList();
385 }
386 }
387 }
388
389 private void populateDirectoryList() {
390 setContentView(R.layout.uploader_layout);
391
392 ListView mListView = (ListView) findViewById(android.R.id.list);
393
394 String current_dir = mParents.peek();
395 if(current_dir.equals("")){
396 getSupportActionBar().setTitle(getString(R.string.default_display_name_for_root_folder));
397 }
398 else{
399 getSupportActionBar().setTitle(current_dir);
400 }
401 boolean notRoot = (mParents.size() > 1);
402 ActionBar actionBar = getSupportActionBar();
403 actionBar.setDisplayHomeAsUpEnabled(notRoot);
404 actionBar.setHomeButtonEnabled(notRoot);
405
406 String full_path = generatePath(mParents);
407
408 Log_OC.d(TAG, "Populating view with content of : " + full_path);
409
410 mFile = getStorageManager().getFileByPath(full_path);
411 if (mFile != null) {
412 Vector<OCFile> files = getStorageManager().getFolderContent(mFile);
413 List<HashMap<String, Object>> data = new LinkedList<HashMap<String,Object>>();
414 for (OCFile f : files) {
415 HashMap<String, Object> h = new HashMap<String, Object>();
416 if (f.isFolder()) {
417 h.put("dirname", f.getFileName());
418 data.add(h);
419 }
420 }
421 SimpleAdapter sa = new SimpleAdapter(this,
422 data,
423 R.layout.uploader_list_item_layout,
424 new String[] {"dirname"},
425 new int[] {R.id.textView1});
426
427 mListView.setAdapter(sa);
428 Button btnChooseFolder = (Button) findViewById(R.id.uploader_choose_folder);
429 btnChooseFolder.setOnClickListener(this);
430
431 Button btnNewFolder = (Button) findViewById(R.id.uploader_new_folder);
432 btnNewFolder.setOnClickListener(this);
433
434 mListView.setOnItemClickListener(this);
435 }
436 }
437
438 private String generatePath(Stack<String> dirs) {
439 String full_path = "";
440
441 for (String a : dirs)
442 full_path += a + "/";
443 return full_path;
444 }
445
446 private void prepareStreamsToUpload() {
447 if (getIntent().getAction().equals(Intent.ACTION_SEND)) {
448 mStreamsToUpload = new ArrayList<Parcelable>();
449 mStreamsToUpload.add(getIntent().getParcelableExtra(Intent.EXTRA_STREAM));
450 } else if (getIntent().getAction().equals(Intent.ACTION_SEND_MULTIPLE)) {
451 mStreamsToUpload = getIntent().getParcelableArrayListExtra(Intent.EXTRA_STREAM);
452 }
453 }
454
455 private boolean somethingToUpload() {
456 return (mStreamsToUpload != null && mStreamsToUpload.get(0) != null);
457 }
458
459 public void uploadFiles() {
460 try {
461
462 // ArrayList for files with path in external storage
463 ArrayList<String> local = new ArrayList<String>();
464 ArrayList<String> remote = new ArrayList<String>();
465
466 // this checks the mimeType
467 for (Parcelable mStream : mStreamsToUpload) {
468
469 Uri uri = (Uri) mStream;
470 String data = null;
471 String filePath = "";
472
473 if (uri != null) {
474 if (uri.getScheme().equals("content")) {
475 String mimeType = getContentResolver().getType(uri);
476
477 if (mimeType.contains("image")) {
478 String[] CONTENT_PROJECTION = { Images.Media.DATA,
479 Images.Media.DISPLAY_NAME, Images.Media.MIME_TYPE,
480 Images.Media.SIZE };
481 Cursor c = getContentResolver().query(uri, CONTENT_PROJECTION, null,
482 null, null);
483 c.moveToFirst();
484 int index = c.getColumnIndex(Images.Media.DATA);
485 data = c.getString(index);
486 filePath = mUploadPath +
487 c.getString(c.getColumnIndex(Images.Media.DISPLAY_NAME));
488
489 } else if (mimeType.contains("video")) {
490 String[] CONTENT_PROJECTION = { Video.Media.DATA,
491 Video.Media.DISPLAY_NAME, Video.Media.MIME_TYPE,
492 Video.Media.SIZE, Video.Media.DATE_MODIFIED };
493 Cursor c = getContentResolver().query(uri, CONTENT_PROJECTION, null,
494 null, null);
495 c.moveToFirst();
496 int index = c.getColumnIndex(Video.Media.DATA);
497 data = c.getString(index);
498 filePath = mUploadPath +
499 c.getString(c.getColumnIndex(Video.Media.DISPLAY_NAME));
500
501 } else if (mimeType.contains("audio")) {
502 String[] CONTENT_PROJECTION = { Audio.Media.DATA,
503 Audio.Media.DISPLAY_NAME, Audio.Media.MIME_TYPE,
504 Audio.Media.SIZE };
505 Cursor c = getContentResolver().query(uri, CONTENT_PROJECTION, null,
506 null, null);
507 c.moveToFirst();
508 int index = c.getColumnIndex(Audio.Media.DATA);
509 data = c.getString(index);
510 filePath = mUploadPath +
511 c.getString(c.getColumnIndex(Audio.Media.DISPLAY_NAME));
512
513 } else {
514 Cursor cursor = getContentResolver().query(uri,
515 new String[]{MediaStore.MediaColumns.DISPLAY_NAME},
516 null, null, null);
517 cursor.moveToFirst();
518 int nameIndex = cursor.getColumnIndex(cursor.getColumnNames()[0]);
519 if (nameIndex >= 0) {
520 filePath = mUploadPath + cursor.getString(nameIndex);
521 }
522 }
523
524 } else if (uri.getScheme().equals("file")) {
525 filePath = Uri.decode(uri.toString()).replace(uri.getScheme() +
526 "://", "");
527 if (filePath.contains("mnt")) {
528 String splitedFilePath[] = filePath.split("/mnt");
529 filePath = splitedFilePath[1];
530 }
531 final File file = new File(filePath);
532 data = file.getAbsolutePath();
533 filePath = mUploadPath + file.getName();
534 }
535 else {
536 throw new SecurityException();
537 }
538 if (data == null) {
539 mRemoteCacheData.add(filePath);
540 CopyTmpFileAsyncTask copyTask = new CopyTmpFileAsyncTask(this);
541 Object[] params = { uri, filePath, mRemoteCacheData.size()-1 };
542 mNumCacheFile++;
543 showWaitingCopyDialog();
544 copyTask.execute(params);
545 } else {
546 remote.add(filePath);
547 local.add(data);
548 }
549 }
550 else {
551 throw new SecurityException();
552 }
553
554 Intent intent = new Intent(getApplicationContext(), FileUploader.class);
555 intent.putExtra(FileUploader.KEY_UPLOAD_TYPE, FileUploader.UPLOAD_MULTIPLE_FILES);
556 intent.putExtra(FileUploader.KEY_LOCAL_FILE, local.toArray(new String[local.size()]));
557 intent.putExtra(FileUploader.KEY_REMOTE_FILE,
558 remote.toArray(new String[remote.size()]));
559 intent.putExtra(FileUploader.KEY_ACCOUNT, getAccount());
560 startService(intent);
561
562 //Save the path to shared preferences
563 SharedPreferences.Editor appPrefs = PreferenceManager
564 .getDefaultSharedPreferences(getApplicationContext()).edit();
565 appPrefs.putString("last_upload_path", mUploadPath);
566 appPrefs.apply();
567
568 finish();
569 }
570
571 } catch (SecurityException e) {
572 String message = String.format(getString(R.string.uploader_error_forbidden_content),
573 getString(R.string.app_name));
574 Toast.makeText(this, message, Toast.LENGTH_LONG).show();
575 }
576 }
577
578 @Override
579 public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) {
580 super.onRemoteOperationFinish(operation, result);
581
582
583 if (operation instanceof CreateFolderOperation) {
584 onCreateFolderOperationFinish((CreateFolderOperation)operation, result);
585 }
586
587 }
588
589 /**
590 * Updates the view associated to the activity after the finish of an operation
591 * trying create a new folder
592 *
593 * @param operation Creation operation performed.
594 * @param result Result of the creation.
595 */
596 private void onCreateFolderOperationFinish(CreateFolderOperation operation,
597 RemoteOperationResult result) {
598 if (result.isSuccess()) {
599 dismissLoadingDialog();
600 populateDirectoryList();
601 } else {
602 dismissLoadingDialog();
603 try {
604 Toast msg = Toast.makeText(this,
605 ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()),
606 Toast.LENGTH_LONG);
607 msg.show();
608
609 } catch (NotFoundException e) {
610 Log_OC.e(TAG, "Error while trying to show fail message " , e);
611 }
612 }
613 }
614
615
616 /**
617 * Loads the target folder initialize shown to the user.
618 *
619 * The target account has to be chosen before this method is called.
620 */
621 private void initTargetFolder() {
622 if (getStorageManager() == null) {
623 throw new IllegalStateException("Do not call this method before " +
624 "initializing mStorageManager");
625 }
626
627 SharedPreferences appPreferences = PreferenceManager
628 .getDefaultSharedPreferences(getApplicationContext());
629
630 String last_path = appPreferences.getString("last_upload_path", "");
631 // "/" equals root-directory
632 if(last_path.equals("/")) {
633 mParents.add("");
634 } else{
635 String[] dir_names = last_path.split("/");
636 for (String dir : dir_names)
637 mParents.add(dir);
638 }
639 //Make sure that path still exists, if it doesn't pop the stack and try the previous path
640 while(!getStorageManager().fileExists(generatePath(mParents)) && mParents.size() > 1){
641 mParents.pop();
642 }
643 }
644
645
646 @Override
647 public boolean onOptionsItemSelected(MenuItem item) {
648 boolean retval = true;
649 switch (item.getItemId()) {
650 case android.R.id.home:
651 if((mParents.size() > 1)) {
652 onBackPressed();
653 }
654 break;
655
656 default:
657 retval = super.onOptionsItemSelected(item);
658 }
659 return retval;
660 }
661
662
663 /**
664 * Process the result of CopyTmpFileAsyncTask
665 * @param result
666 * @param index
667 */
668 @Override
669 public void OnCopyTmpFileTaskListener(String result, int index) {
670 if (mNumCacheFile -- == 0) {
671 dismissWaitingCopyDialog();
672 }
673 if (result != null) {
674 Intent intent = new Intent(getApplicationContext(), FileUploader.class);
675 intent.putExtra(FileUploader.KEY_UPLOAD_TYPE, FileUploader.UPLOAD_SINGLE_FILE);
676 intent.putExtra(FileUploader.KEY_LOCAL_FILE, result);
677 intent.putExtra(FileUploader.KEY_REMOTE_FILE, mRemoteCacheData.get(index));
678 intent.putExtra(FileUploader.KEY_ACCOUNT, getAccount());
679 startService(intent);
680
681 } else {
682 String message = String.format(getString(R.string.uploader_error_forbidden_content),
683 getString(R.string.app_name));
684 Toast.makeText(this, message, Toast.LENGTH_LONG).show();
685 Log_OC.d(TAG, message);
686 }
687
688 }
689 /**
690 * Show waiting for copy dialog
691 */
692 public void showWaitingCopyDialog() {
693 // Construct dialog
694 LoadingDialog loading = new LoadingDialog(
695 getResources().getString(R.string.wait_for_tmp_copy_from_private_storage));
696 FragmentManager fm = getSupportFragmentManager();
697 FragmentTransaction ft = fm.beginTransaction();
698 loading.show(ft, DIALOG_WAIT_COPY_FILE);
699
700 }
701
702
703 /**
704 * Dismiss waiting for copy dialog
705 */
706 public void dismissWaitingCopyDialog(){
707 Fragment frag = getSupportFragmentManager().findFragmentByTag(DIALOG_WAIT_COPY_FILE);
708 if (frag != null) {
709 LoadingDialog loading = (LoadingDialog) frag;
710 loading.dismiss();
711 }
712 }
713 }