Merge remote-tracking branch 'remotes/upstream/externalSD2' into beta
[pub/Android/ownCloud.git] / src / com / owncloud / android / ui / activity / Preferences.java
1 /**
2 * ownCloud Android client application
3 *
4 * @author Bartek Przybylski
5 * @author David A. Velasco
6 * Copyright (C) 2011 Bartek Przybylski
7 * Copyright (C) 2015 ownCloud Inc.
8 *
9 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2,
11 * as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22 package com.owncloud.android.ui.activity;
23
24 import android.accounts.Account;
25 import android.accounts.AccountManager;
26 import android.accounts.AccountManagerCallback;
27 import android.accounts.AccountManagerFuture;
28 import android.content.ComponentName;
29 import android.content.Context;
30 import android.content.Intent;
31 import android.content.ServiceConnection;
32 import android.content.SharedPreferences;
33 import android.content.pm.PackageInfo;
34 import android.content.pm.PackageManager.NameNotFoundException;
35 import android.content.res.Configuration;
36 import android.net.Uri;
37 import android.os.AsyncTask;
38 import android.os.Bundle;
39 import android.os.Environment;
40 import android.os.Handler;
41 import android.os.IBinder;
42 import android.preference.CheckBoxPreference;
43 import android.preference.Preference;
44 import android.preference.Preference.OnPreferenceChangeListener;
45 import android.preference.Preference.OnPreferenceClickListener;
46 import android.preference.PreferenceActivity;
47 import android.preference.PreferenceCategory;
48 import android.preference.PreferenceManager;
49 import android.support.annotation.LayoutRes;
50 import android.support.annotation.Nullable;
51 import android.support.v7.app.ActionBar;
52 import android.support.v7.app.AlertDialog;
53 import android.support.v7.app.AppCompatDelegate;
54 import android.support.v7.widget.Toolbar;
55 import android.view.ContextMenu;
56 import android.view.ContextMenu.ContextMenuInfo;
57 import android.view.Menu;
58 import android.view.MenuInflater;
59 import android.view.MenuItem;
60 import android.view.View;
61 import android.view.ViewGroup;
62 import android.widget.AdapterView;
63 import android.widget.AdapterView.OnItemLongClickListener;
64 import android.widget.ArrayAdapter;
65 import android.widget.ListAdapter;
66 import android.widget.ListView;
67 import android.widget.Toast;
68
69 import com.owncloud.android.BuildConfig;
70 import com.owncloud.android.MainApp;
71 import com.owncloud.android.R;
72 import com.owncloud.android.authentication.AccountUtils;
73 import com.owncloud.android.authentication.AuthenticatorActivity;
74 import com.owncloud.android.datamodel.FileDataStorageManager;
75 import com.owncloud.android.datamodel.OCFile;
76 import com.owncloud.android.datamodel.ThumbnailsCacheManager;
77 import com.owncloud.android.db.DbHandler;
78 import com.owncloud.android.files.FileOperationsHelper;
79 import com.owncloud.android.files.services.FileDownloader;
80 import com.owncloud.android.files.services.FileUploader;
81 import com.owncloud.android.lib.common.utils.Log_OC;
82 import com.owncloud.android.services.OperationsService;
83 import com.owncloud.android.ui.PreferenceWithLongSummary;
84 import com.owncloud.android.ui.RadioButtonPreference;
85 import com.owncloud.android.utils.DisplayUtils;
86
87 import java.io.BufferedReader;
88 import java.io.IOException;
89 import java.io.InputStreamReader;
90 import java.net.MalformedURLException;
91 import java.net.URL;
92 import java.util.concurrent.ExecutionException;
93 import java.io.File;
94
95
96 /**
97 * An Activity that allows the user to change the application's settings.
98 *
99 * It proxies the necessary calls via {@link android.support.v7.app.AppCompatDelegate} to be used
100 * with AppCompat.
101 */
102 public class Preferences extends PreferenceActivity
103 implements AccountManagerCallback<Boolean>, ComponentsGetter {
104
105 private static final String TAG = "OwnCloudPreferences";
106
107 private static final int ACTION_SELECT_UPLOAD_PATH = 1;
108 private static final int ACTION_SELECT_UPLOAD_VIDEO_PATH = 2;
109 private static final int ACTION_SELECT_STORAGE_PATH = 3;
110 private static final int ACTION_PERFORM_MIGRATION = 4;
111
112 private DbHandler mDbHandler;
113 private CheckBoxPreference pCode;
114 private Preference pAboutApp;
115 private AppCompatDelegate mDelegate;
116
117 private PreferenceCategory mAccountsPrefCategory = null;
118 private final Handler mHandler = new Handler();
119 private String mAccountName;
120 private boolean mShowContextMenu = false;
121 private String mUploadPath;
122 private PreferenceCategory mPrefInstantUploadCategory;
123 private Preference mPrefInstantUpload;
124 private Preference mPrefInstantUploadPath;
125 private Preference mPrefInstantUploadPathWiFi;
126 private Preference mPrefInstantVideoUpload;
127 private Preference mPrefInstantVideoUploadPath;
128 private Preference mPrefInstantVideoUploadPathWiFi;
129 private String mUploadVideoPath;
130
131 protected FileDownloader.FileDownloaderBinder mDownloaderBinder = null;
132 protected FileUploader.FileUploaderBinder mUploaderBinder = null;
133 private ServiceConnection mDownloadServiceConnection, mUploadServiceConnection = null;
134 private PreferenceWithLongSummary mPrefStoragePath;
135 private String mStoragePath;
136
137 @SuppressWarnings("deprecation")
138 @Override
139 public void onCreate(Bundle savedInstanceState) {
140 getDelegate().installViewFactory();
141 getDelegate().onCreate(savedInstanceState);
142 super.onCreate(savedInstanceState);
143 mDbHandler = new DbHandler(getBaseContext());
144 addPreferencesFromResource(R.xml.preferences);
145
146 ActionBar actionBar = getSupportActionBar();
147 actionBar.setDisplayHomeAsUpEnabled(true);
148 actionBar.setTitle(R.string.actionbar_settings);
149
150 // For adding content description tag to a title field in the action bar
151 int actionBarTitleId = getResources().getIdentifier("action_bar_title", "id", "android");
152 View actionBarTitleView = getWindow().getDecorView().findViewById(actionBarTitleId);
153 if (actionBarTitleView != null) { // it's null in Android 2.x
154 getWindow().getDecorView().findViewById(actionBarTitleId).
155 setContentDescription(getString(R.string.actionbar_settings));
156 }
157
158 // Load the accounts category for adding the list of accounts
159 mAccountsPrefCategory = (PreferenceCategory) findPreference("accounts_category");
160
161 ListView listView = getListView();
162 listView.setOnItemLongClickListener(new OnItemLongClickListener() {
163 @Override
164 public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
165 ListView listView = (ListView) parent;
166 ListAdapter listAdapter = listView.getAdapter();
167 Object obj = listAdapter.getItem(position);
168
169 if (obj != null && obj instanceof RadioButtonPreference) {
170 mShowContextMenu = true;
171 mAccountName = ((RadioButtonPreference) obj).getKey();
172
173 String[] items = {
174 getResources().getString(R.string.change_password),
175 getResources().getString(R.string.delete_account)
176 };
177 final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(Preferences.this);
178 View convertView = getLayoutInflater().inflate(R.layout.alert_dialog_list_view, null);
179 alertDialogBuilder.setView(convertView);
180 ListView lv = (ListView) convertView.findViewById(R.id.list);
181 ArrayAdapter<String> adapter = new ArrayAdapter<String>(
182 Preferences.this,R.layout.simple_dialog_list_item,items);
183 lv.setAdapter(adapter);
184
185 //Setup proper inline listener
186 final AlertDialog alertDialog = alertDialogBuilder.create();
187 lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
188 @Override
189 public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
190 AccountManager am = (AccountManager) getSystemService(ACCOUNT_SERVICE);
191 Account accounts[] = am.getAccountsByType(MainApp.getAccountType());
192 for (Account a : accounts) {
193 if (a.name.equals(mAccountName)) {
194 if (position==0) {
195
196 // Change account password
197 Intent updateAccountCredentials = new Intent(Preferences.this, AuthenticatorActivity.class);
198 updateAccountCredentials.putExtra(AuthenticatorActivity.EXTRA_ACCOUNT, a);
199 updateAccountCredentials.putExtra(AuthenticatorActivity.EXTRA_ACTION,
200 AuthenticatorActivity.ACTION_UPDATE_TOKEN);
201 startActivity(updateAccountCredentials);
202 alertDialog.cancel();
203
204 } else if (position==1) {
205
206 // Remove account
207 am.removeAccount(a, Preferences.this, mHandler);
208 Log_OC.d(TAG, "Remove an account " + a.name);
209 alertDialog.cancel();
210 }
211 }
212 }
213 }
214 });
215 alertDialog.show();
216
217 View.OnLongClickListener longListener = (View.OnLongClickListener) obj;
218 return longListener.onLongClick(view);
219 }
220 return false;
221 }
222 });
223
224 // Load package info
225 String temp;
226 try {
227 PackageInfo pkg = getPackageManager().getPackageInfo(getPackageName(), 0);
228 temp = pkg.versionName;
229 } catch (NameNotFoundException e) {
230 temp = "";
231 Log_OC.e(TAG, "Error while showing about dialog", e);
232 }
233 final String appVersion = temp;
234
235 // Register context menu for list of preferences.
236 registerForContextMenu(getListView());
237
238 pCode = (CheckBoxPreference) findPreference("set_pincode");
239 if (pCode != null){
240 pCode.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
241 @Override
242 public boolean onPreferenceChange(Preference preference, Object newValue) {
243 Intent i = new Intent(getApplicationContext(), PassCodeActivity.class);
244 Boolean enable = (Boolean) newValue;
245 i.setAction(
246 enable.booleanValue() ? PassCodeActivity.ACTION_ENABLE :
247 PassCodeActivity.ACTION_DISABLE
248 );
249 startActivity(i);
250
251 return true;
252 }
253 });
254
255 }
256
257 final Preference pCacheSize = findPreference("pref_cache_size");
258 if (pCacheSize != null){
259 final SharedPreferences appPrefs =
260 PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
261 Long cacheSize = ThumbnailsCacheManager.getMaxSize();
262 pCacheSize.setSummary(cacheSize + " Mb");
263 pCacheSize.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
264 @Override
265 public boolean onPreferenceChange(Preference preference, Object newValue) {
266 Long size = Long.decode((String) newValue);
267 if (ThumbnailsCacheManager.setMaxSize(size)){
268 appPrefs.edit().putString("pref_cache_size", size.toString());
269 pCacheSize.setSummary(size + " MB");
270 return true;
271 } else {
272 return false;
273 }
274 }
275 });
276 }
277
278 PreferenceCategory preferenceCategory = (PreferenceCategory) findPreference("more");
279
280 boolean helpEnabled = getResources().getBoolean(R.bool.help_enabled);
281 Preference pHelp = findPreference("help");
282 if (pHelp != null ){
283 if (helpEnabled) {
284 pHelp.setOnPreferenceClickListener(new OnPreferenceClickListener() {
285 @Override
286 public boolean onPreferenceClick(Preference preference) {
287 String helpWeb =(String) getText(R.string.url_help);
288 if (helpWeb != null && helpWeb.length() > 0) {
289 Uri uriUrl = Uri.parse(helpWeb);
290 Intent intent = new Intent(Intent.ACTION_VIEW, uriUrl);
291 startActivity(intent);
292 }
293 return true;
294 }
295 });
296 } else {
297 preferenceCategory.removePreference(pHelp);
298 }
299
300 }
301
302 if (BuildConfig.DEBUG) {
303 Preference pLog = findPreference("log");
304 if (pLog != null ){
305 pLog.setOnPreferenceClickListener(new OnPreferenceClickListener() {
306 @Override
307 public boolean onPreferenceClick(Preference preference) {
308 Intent loggerIntent = new Intent(getApplicationContext(),
309 LogHistoryActivity.class);
310 startActivity(loggerIntent);
311 return true;
312 }
313 });
314 }
315 }
316
317 boolean recommendEnabled = getResources().getBoolean(R.bool.recommend_enabled);
318 Preference pRecommend = findPreference("recommend");
319 if (pRecommend != null){
320 if (recommendEnabled) {
321 pRecommend.setOnPreferenceClickListener(new OnPreferenceClickListener() {
322 @Override
323 public boolean onPreferenceClick(Preference preference) {
324
325 Intent intent = new Intent(Intent.ACTION_SENDTO);
326 intent.setType("text/plain");
327 intent.setData(Uri.parse(getString(R.string.mail_recommend)));
328 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
329
330 String appName = getString(R.string.app_name);
331 String downloadUrl = getString(R.string.url_app_download);
332 Account currentAccount = AccountUtils.
333 getCurrentOwnCloudAccount(Preferences.this);
334 String username = currentAccount.name.substring(0,
335 currentAccount.name.lastIndexOf('@'));
336
337 String recommendSubject = String.format(getString(R.string.recommend_subject),
338 appName);
339 String recommendText = String.format(getString(R.string.recommend_text),
340 appName, downloadUrl);
341
342 intent.putExtra(Intent.EXTRA_SUBJECT, recommendSubject);
343 intent.putExtra(Intent.EXTRA_TEXT, recommendText);
344 startActivity(intent);
345
346 return true;
347
348 }
349 });
350 } else {
351 preferenceCategory.removePreference(pRecommend);
352 }
353
354 }
355
356 boolean feedbackEnabled = getResources().getBoolean(R.bool.feedback_enabled);
357 Preference pFeedback = findPreference("feedback");
358 if (pFeedback != null){
359 if (feedbackEnabled) {
360 pFeedback.setOnPreferenceClickListener(new OnPreferenceClickListener() {
361 @Override
362 public boolean onPreferenceClick(Preference preference) {
363 String feedbackMail = (String) getText(R.string.mail_feedback);
364 String feedback = String.format("%s - android v%s", getText(R.string.prefs_feedback), appVersion);
365 Intent intent = new Intent(Intent.ACTION_SENDTO);
366
367 intent.setType("text/plain");
368 intent.putExtra(Intent.EXTRA_SUBJECT, feedback);
369
370 intent.setData(Uri.parse(feedbackMail));
371 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
372 startActivity(intent);
373
374 return true;
375 }
376 });
377 } else {
378 preferenceCategory.removePreference(pFeedback);
379 }
380
381 }
382
383 boolean imprintEnabled = getResources().getBoolean(R.bool.imprint_enabled);
384 Preference pImprint = findPreference("imprint");
385 if (pImprint != null) {
386 if (imprintEnabled) {
387 pImprint.setOnPreferenceClickListener(new OnPreferenceClickListener() {
388 @Override
389 public boolean onPreferenceClick(Preference preference) {
390 String imprintWeb = (String) getText(R.string.url_imprint);
391 if (imprintWeb != null && imprintWeb.length() > 0) {
392 Uri uriUrl = Uri.parse(imprintWeb);
393 Intent intent = new Intent(Intent.ACTION_VIEW, uriUrl);
394 startActivity(intent);
395 }
396 //ImprintDialog.newInstance(true).show(preference.get, "IMPRINT_DIALOG");
397 return true;
398 }
399 });
400 } else {
401 preferenceCategory.removePreference(pImprint);
402 }
403 }
404
405 mPrefStoragePath = (PreferenceWithLongSummary)findPreference("storage_path");
406 if (mPrefStoragePath != null) {
407
408 mPrefStoragePath.setOnPreferenceClickListener(new OnPreferenceClickListener() {
409 @Override
410 public boolean onPreferenceClick(Preference preference) {
411 Intent intent = new Intent(Preferences.this, LocalDirectorySelectorActivity.class);
412 intent.putExtra(UploadFilesActivity.KEY_DIRECTORY_PATH, mStoragePath);
413 startActivityForResult(intent, ACTION_SELECT_STORAGE_PATH);
414 return true;
415 }
416 });
417
418 mPrefStoragePath.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
419 @Override
420 public boolean onPreferenceChange(Preference preference, Object newValue) {
421 MainApp.setStoragePath((String) newValue);
422 return true;
423 }
424 });
425 }
426
427 mPrefInstantUploadPath = (PreferenceWithLongSummary)findPreference("instant_upload_path");
428 if (mPrefInstantUploadPath != null){
429
430 mPrefInstantUploadPath.setOnPreferenceClickListener(new OnPreferenceClickListener() {
431 @Override
432 public boolean onPreferenceClick(Preference preference) {
433 if (!mUploadPath.endsWith(OCFile.PATH_SEPARATOR)) {
434 mUploadPath += OCFile.PATH_SEPARATOR;
435 }
436 Intent intent = new Intent(Preferences.this, UploadPathActivity.class);
437 intent.putExtra(UploadPathActivity.KEY_INSTANT_UPLOAD_PATH, mUploadPath);
438 startActivityForResult(intent, ACTION_SELECT_UPLOAD_PATH);
439 return true;
440 }
441 });
442 }
443
444 mPrefInstantUploadCategory =
445 (PreferenceCategory) findPreference("instant_uploading_category");
446
447 mPrefInstantUploadPathWiFi = findPreference("instant_upload_on_wifi");
448 mPrefInstantUpload = findPreference("instant_uploading");
449
450 toggleInstantPictureOptions(((CheckBoxPreference) mPrefInstantUpload).isChecked());
451
452 mPrefInstantUpload.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
453
454 @Override
455 public boolean onPreferenceChange(Preference preference, Object newValue) {
456 toggleInstantPictureOptions((Boolean) newValue);
457 return true;
458 }
459 });
460
461 mPrefInstantVideoUploadPath = findPreference("instant_video_upload_path");
462 if (mPrefInstantVideoUploadPath != null){
463
464 mPrefInstantVideoUploadPath.setOnPreferenceClickListener(new OnPreferenceClickListener() {
465 @Override
466 public boolean onPreferenceClick(Preference preference) {
467 if (!mUploadVideoPath.endsWith(OCFile.PATH_SEPARATOR)) {
468 mUploadVideoPath += OCFile.PATH_SEPARATOR;
469 }
470 Intent intent = new Intent(Preferences.this, UploadPathActivity.class);
471 intent.putExtra(UploadPathActivity.KEY_INSTANT_UPLOAD_PATH,
472 mUploadVideoPath);
473 startActivityForResult(intent, ACTION_SELECT_UPLOAD_VIDEO_PATH);
474 return true;
475 }
476 });
477 }
478
479 mPrefInstantVideoUploadPathWiFi = findPreference("instant_video_upload_on_wifi");
480 mPrefInstantVideoUpload = findPreference("instant_video_uploading");
481 toggleInstantVideoOptions(((CheckBoxPreference) mPrefInstantVideoUpload).isChecked());
482
483 mPrefInstantVideoUpload.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
484
485 @Override
486 public boolean onPreferenceChange(Preference preference, Object newValue) {
487 toggleInstantVideoOptions((Boolean) newValue);
488 return true;
489 }
490 });
491
492 /* About App */
493 pAboutApp = findPreference("about_app");
494 if (pAboutApp != null) {
495 pAboutApp.setTitle(String.format(getString(R.string.about_android),
496 getString(R.string.app_name)));
497 try {
498 Integer currentVersion = getPackageManager().getPackageInfo
499 (getPackageName(), 0).versionCode;
500 pAboutApp.setSummary(String.format(getString(R.string.about_version),
501 currentVersion));
502 } catch (NameNotFoundException e) {
503 }
504 }
505
506 loadInstantUploadPath();
507 loadStoragePath();
508 loadInstantUploadVideoPath();
509
510 /* ComponentsGetter */
511 mDownloadServiceConnection = newTransferenceServiceConnection();
512 if (mDownloadServiceConnection != null) {
513 bindService(new Intent(this, FileDownloader.class), mDownloadServiceConnection,
514 Context.BIND_AUTO_CREATE);
515 }
516 mUploadServiceConnection = newTransferenceServiceConnection();
517 if (mUploadServiceConnection != null) {
518 bindService(new Intent(this, FileUploader.class), mUploadServiceConnection,
519 Context.BIND_AUTO_CREATE);
520 }
521
522 /* Link to Beta apks */
523 Preference pBetaLink = findPreference("beta_link");
524 if (pBetaLink != null ){
525 pBetaLink.setOnPreferenceClickListener(new OnPreferenceClickListener() {
526 @Override
527 public boolean onPreferenceClick(Preference preference) {
528 Integer latestVersion = -1;
529 Integer currentVersion = -1;
530 try {
531 currentVersion = getPackageManager().getPackageInfo
532 (getPackageName(), 0).versionCode;
533 LoadingVersionNumberTask loadTask = new LoadingVersionNumberTask();
534 loadTask.execute();
535 latestVersion = loadTask.get();
536 } catch (InterruptedException | ExecutionException e) {
537 e.printStackTrace();
538 } catch (NameNotFoundException e) {
539 e.printStackTrace();
540 }
541 if (latestVersion == -1 || currentVersion == -1) {
542 Toast.makeText(getApplicationContext(), "No information available!",
543 Toast.LENGTH_SHORT).show();
544 }
545 if (latestVersion > currentVersion) {
546 String betaLinkWeb = (String) getText(R.string.beta_link) +
547 latestVersion + ".apk";
548 if (betaLinkWeb != null && betaLinkWeb.length() > 0) {
549 Uri uriUrl = Uri.parse(betaLinkWeb);
550 Intent intent = new Intent(Intent.ACTION_VIEW, uriUrl);
551 startActivity(intent);
552 return true;
553 }
554 } else {
555 Toast.makeText(getApplicationContext(), "No new version available!",
556 Toast.LENGTH_SHORT).show();
557 return true;
558 }
559 return true;
560 }
561 });
562 }
563
564 /* Link to Beta apks */
565 Preference pChangelogLink = findPreference("changelog_link");
566 if (pChangelogLink != null) {
567 pChangelogLink.setOnPreferenceClickListener(new OnPreferenceClickListener() {
568 @Override
569 public boolean onPreferenceClick(Preference preference) {
570 String betaLinkWeb = getString(R.string.changelog);
571 if (betaLinkWeb != null && betaLinkWeb.length() > 0) {
572 Uri uriUrl = Uri.parse(betaLinkWeb);
573 Intent intent = new Intent(Intent.ACTION_VIEW, uriUrl);
574 startActivity(intent);
575 return true;
576 }
577 return true;
578 }
579 });
580 }
581 }
582
583 private void toggleInstantPictureOptions(Boolean value){
584 if (value){
585 mPrefInstantUploadCategory.addPreference(mPrefInstantUploadPathWiFi);
586 mPrefInstantUploadCategory.addPreference(mPrefInstantUploadPath);
587 } else {
588 // mPrefInstantUploadCategory.removePreference(mPrefInstantUploadPathWiFi);
589 // mPrefInstantUploadCategory.removePreference(mPrefInstantUploadPath);
590 }
591 }
592
593 private void toggleInstantVideoOptions(Boolean value){
594 if (value){
595 mPrefInstantUploadCategory.addPreference(mPrefInstantVideoUploadPathWiFi);
596 mPrefInstantUploadCategory.addPreference(mPrefInstantVideoUploadPath);
597 } else {
598 // mPrefInstantUploadCategory.removePreference(mPrefInstantVideoUploadPathWiFi);
599 // mPrefInstantUploadCategory.removePreference(mPrefInstantVideoUploadPath);
600 }
601 }
602
603 @Override
604 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
605
606 // Filter for only showing contextual menu when long press on the
607 // accounts
608 if (mShowContextMenu) {
609 getMenuInflater().inflate(R.menu.account_picker_long_click, menu);
610 mShowContextMenu = false;
611 }
612 super.onCreateContextMenu(menu, v, menuInfo);
613 }
614
615 @Override
616 public void run(AccountManagerFuture<Boolean> future) {
617 if (future.isDone()) {
618 // after remove account
619 Account account = new Account(mAccountName, MainApp.getAccountType());
620 if (!AccountUtils.exists(account, MainApp.getAppContext())) {
621 // Cancel tranfers
622 if (mUploaderBinder != null) {
623 mUploaderBinder.cancel(account);
624 }
625 if (mDownloaderBinder != null) {
626 mDownloaderBinder.cancel(account);
627 }
628 }
629
630 Account a = AccountUtils.getCurrentOwnCloudAccount(this);
631 String accountName = "";
632 if (a == null) {
633 Account[] accounts = AccountManager.get(this)
634 .getAccountsByType(MainApp.getAccountType());
635 if (accounts.length != 0)
636 accountName = accounts[0].name;
637 AccountUtils.setCurrentOwnCloudAccount(this, accountName);
638 }
639 addAccountsCheckboxPreferences();
640 }
641 }
642
643 @Override
644 protected void onResume() {
645 super.onResume();
646 SharedPreferences appPrefs =
647 PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
648 boolean state = appPrefs.getBoolean("set_pincode", false);
649 pCode.setChecked(state);
650
651 // Populate the accounts category with the list of accounts
652 addAccountsCheckboxPreferences();
653 }
654
655 @Override
656 public boolean onCreateOptionsMenu(Menu menu) {
657 super.onCreateOptionsMenu(menu);
658 return true;
659 }
660
661 @Override
662 public boolean onMenuItemSelected(int featureId, MenuItem item) {
663 super.onMenuItemSelected(featureId, item);
664 Intent intent;
665
666 switch (item.getItemId()) {
667 case android.R.id.home:
668 intent = new Intent(getBaseContext(), FileDisplayActivity.class);
669 intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
670 startActivity(intent);
671 break;
672 default:
673 Log_OC.w(TAG, "Unknown menu item triggered");
674 return false;
675 }
676 return true;
677 }
678
679 @Override
680 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
681 super.onActivityResult(requestCode, resultCode, data);
682
683 if (requestCode == ACTION_SELECT_UPLOAD_PATH && resultCode == RESULT_OK){
684
685 OCFile folderToUpload = data.getParcelableExtra(UploadPathActivity.EXTRA_FOLDER);
686
687 mUploadPath = folderToUpload.getRemotePath();
688
689 mUploadPath = DisplayUtils.getPathWithoutLastSlash(mUploadPath);
690
691 // Show the path on summary preference
692 mPrefInstantUploadPath.setSummary(mUploadPath);
693
694 saveInstantUploadPathOnPreferences();
695
696 } else if (requestCode == ACTION_SELECT_UPLOAD_VIDEO_PATH && resultCode == RESULT_OK) {
697
698 OCFile folderToUploadVideo = data.getParcelableExtra(UploadPathActivity.EXTRA_FOLDER);
699
700 mUploadVideoPath = folderToUploadVideo.getRemotePath();
701
702 mUploadVideoPath = DisplayUtils.getPathWithoutLastSlash(mUploadVideoPath);
703
704 // Show the video path on summary preference
705 mPrefInstantVideoUploadPath.setSummary(mUploadVideoPath);
706
707 saveInstantUploadVideoPathOnPreferences();
708 } else if (requestCode == ACTION_SELECT_STORAGE_PATH && resultCode == RESULT_OK) {
709 File currentStorageDir = new File(mStoragePath);
710 File upcomingStorageDir = new File(data.getStringExtra(UploadFilesActivity.EXTRA_CHOSEN_FILES));
711
712 if (currentStorageDir != upcomingStorageDir) {
713 Intent migrationIntent = new Intent(this, StorageMigrationActivity.class);
714 migrationIntent.putExtra(StorageMigrationActivity.KEY_MIGRATION_SOURCE_DIR,
715 currentStorageDir.getAbsolutePath());
716 migrationIntent.putExtra(StorageMigrationActivity.KEY_MIGRATION_TARGET_DIR,
717 upcomingStorageDir.getAbsolutePath());
718 startActivityForResult(migrationIntent, ACTION_PERFORM_MIGRATION);
719 }
720 } else if (requestCode == ACTION_PERFORM_MIGRATION && resultCode == RESULT_OK) {
721 String resultStorageDir = data.getStringExtra(StorageMigrationActivity.KEY_MIGRATION_TARGET_DIR);
722 saveStoragePath(resultStorageDir);
723 }
724 }
725
726 public ActionBar getSupportActionBar() {
727 return getDelegate().getSupportActionBar();
728 }
729
730 public void setSupportActionBar(@Nullable Toolbar toolbar) {
731 getDelegate().setSupportActionBar(toolbar);
732 }
733
734 @Override
735 public MenuInflater getMenuInflater() {
736 return getDelegate().getMenuInflater();
737 }
738
739 @Override
740 public void setContentView(@LayoutRes int layoutResID) {
741 getDelegate().setContentView(layoutResID);
742 }
743 @Override
744 public void setContentView(View view) {
745 getDelegate().setContentView(view);
746 }
747
748 @Override
749 public void setContentView(View view, ViewGroup.LayoutParams params) {
750 getDelegate().setContentView(view, params);
751 }
752
753 @Override
754 public void addContentView(View view, ViewGroup.LayoutParams params) {
755 getDelegate().addContentView(view, params);
756 }
757
758 @Override
759 protected void onPostResume() {
760 super.onPostResume();
761 getDelegate().onPostResume();
762 }
763
764 @Override
765 protected void onTitleChanged(CharSequence title, int color) {
766 super.onTitleChanged(title, color);
767 getDelegate().setTitle(title);
768 }
769
770 @Override
771 public void onConfigurationChanged(Configuration newConfig) {
772 super.onConfigurationChanged(newConfig);
773 getDelegate().onConfigurationChanged(newConfig);
774 }
775
776 @Override
777 protected void onPostCreate(Bundle savedInstanceState) {
778 super.onPostCreate(savedInstanceState);
779 getDelegate().onPostCreate(savedInstanceState);
780 }
781
782 @Override
783 protected void onDestroy() {
784 mDbHandler.close();
785
786 if (mDownloadServiceConnection != null) {
787 unbindService(mDownloadServiceConnection);
788 mDownloadServiceConnection = null;
789 }
790 if (mUploadServiceConnection != null) {
791 unbindService(mUploadServiceConnection);
792 mUploadServiceConnection = null;
793 }
794
795 super.onDestroy();
796 getDelegate().onDestroy();
797 }
798
799 @Override
800 protected void onStop() {
801 super.onStop();
802 getDelegate().onStop();
803 }
804
805 public void invalidateOptionsMenu() {
806 getDelegate().invalidateOptionsMenu();
807 }
808
809 private AppCompatDelegate getDelegate() {
810 if (mDelegate == null) {
811 mDelegate = AppCompatDelegate.create(this, null);
812 }
813 return mDelegate;
814 }
815
816 /**
817 * Create the list of accounts that has been added into the app
818 */
819 @SuppressWarnings("deprecation")
820 private void addAccountsCheckboxPreferences() {
821
822 // Remove accounts in case list is refreshing for avoiding to have
823 // duplicate items
824 if (mAccountsPrefCategory.getPreferenceCount() > 0) {
825 mAccountsPrefCategory.removeAll();
826 }
827
828 AccountManager am = (AccountManager) getSystemService(ACCOUNT_SERVICE);
829 Account accounts[] = am.getAccountsByType(MainApp.getAccountType());
830 Account currentAccount = AccountUtils.getCurrentOwnCloudAccount(getApplicationContext());
831
832 if (am.getAccountsByType(MainApp.getAccountType()).length == 0) {
833 // Show create account screen if there isn't any account
834 am.addAccount(MainApp.getAccountType(), null, null, null, this,
835 null,
836 null);
837 }
838 else {
839
840 for (Account a : accounts) {
841 RadioButtonPreference accountPreference = new RadioButtonPreference(this);
842 accountPreference.setKey(a.name);
843 // Handle internationalized domain names
844 accountPreference.setTitle(DisplayUtils.convertIdn(a.name, false));
845 mAccountsPrefCategory.addPreference(accountPreference);
846
847 // Check the current account that is being used
848 if (a.name.equals(currentAccount.name)) {
849 accountPreference.setChecked(true);
850 } else {
851 accountPreference.setChecked(false);
852 }
853
854 accountPreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
855 @Override
856 public boolean onPreferenceChange(Preference preference, Object newValue) {
857 String key = preference.getKey();
858 AccountManager am = (AccountManager) getSystemService(ACCOUNT_SERVICE);
859 Account accounts[] = am.getAccountsByType(MainApp.getAccountType());
860 for (Account a : accounts) {
861 RadioButtonPreference p =
862 (RadioButtonPreference) findPreference(a.name);
863 if (key.equals(a.name)) {
864 boolean accountChanged = !p.isChecked();
865 p.setChecked(true);
866 AccountUtils.setCurrentOwnCloudAccount(
867 getApplicationContext(),
868 a.name
869 );
870 if (accountChanged) {
871 // restart the main activity
872 Intent i = new Intent(
873 Preferences.this,
874 FileDisplayActivity.class
875 );
876 i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
877 i.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
878 startActivity(i);
879 } else {
880 finish();
881 }
882 } else {
883 p.setChecked(false);
884 }
885 }
886 return (Boolean) newValue;
887 }
888 });
889
890 }
891
892 // Add Create Account preference at the end of account list if
893 // Multiaccount is enabled
894 if (getResources().getBoolean(R.bool.multiaccount_support)) {
895 createAddAccountPreference();
896 }
897
898 }
899 }
900
901 /**
902 * Create the preference for allow adding new accounts
903 */
904 private void createAddAccountPreference() {
905 Preference addAccountPref = new Preference(this);
906 addAccountPref.setKey("add_account");
907 addAccountPref.setTitle(getString(R.string.prefs_add_account));
908 mAccountsPrefCategory.addPreference(addAccountPref);
909
910 addAccountPref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
911 @Override
912 public boolean onPreferenceClick(Preference preference) {
913 AccountManager am = AccountManager.get(getApplicationContext());
914 am.addAccount(MainApp.getAccountType(), null, null, null, Preferences.this,
915 null, null);
916 return true;
917 }
918 });
919
920 }
921
922 /**
923 * Load upload path set on preferences
924 */
925 private void loadInstantUploadPath() {
926 SharedPreferences appPrefs =
927 PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
928 mUploadPath = appPrefs.getString("instant_upload_path", getString(R.string.instant_upload_path));
929 mPrefInstantUploadPath.setSummary(mUploadPath);
930 }
931
932 /**
933 * Save storage path
934 */
935 private void saveStoragePath(String newStoragePath) {
936 SharedPreferences appPrefs =
937 PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
938 mStoragePath = newStoragePath;
939 MainApp.setStoragePath(mStoragePath);
940 SharedPreferences.Editor editor = appPrefs.edit();
941 editor.putString("storage_path", mStoragePath);
942 editor.commit();
943 mPrefStoragePath.setSummary(mStoragePath);
944 }
945
946 /**
947 * Load storage path set on preferences
948 */
949 private void loadStoragePath() {
950 SharedPreferences appPrefs =
951 PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
952 mStoragePath = appPrefs.getString("storage_path", Environment.getExternalStorageDirectory()
953 .getAbsolutePath());
954 mPrefStoragePath.setSummary(mStoragePath);
955 }
956
957 /**
958 * Save the "Instant Upload Path" on preferences
959 */
960 private void saveInstantUploadPathOnPreferences() {
961 SharedPreferences appPrefs =
962 PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
963 SharedPreferences.Editor editor = appPrefs.edit();
964 editor.putString("instant_upload_path", mUploadPath);
965 editor.commit();
966 }
967
968 /**
969 * Load upload video path set on preferences
970 */
971 private void loadInstantUploadVideoPath() {
972 mPrefInstantVideoUploadPath.setSummary(MainApp.getStoragePath());
973 }
974
975 /**
976 * Save the "Instant Video Upload Path" on preferences
977 */
978 private void saveInstantUploadVideoPathOnPreferences() {
979 SharedPreferences appPrefs =
980 PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
981 SharedPreferences.Editor editor = appPrefs.edit();
982 editor.putString("instant_video_upload_path", mUploadVideoPath);
983 editor.commit();
984 }
985
986 // Methods for ComponentsGetter
987 @Override
988 public FileDownloader.FileDownloaderBinder getFileDownloaderBinder() {
989 return mDownloaderBinder;
990 }
991
992
993 @Override
994 public FileUploader.FileUploaderBinder getFileUploaderBinder() {
995 return mUploaderBinder;
996 }
997
998 @Override
999 public OperationsService.OperationsServiceBinder getOperationsServiceBinder() {
1000 return null;
1001 }
1002
1003 @Override
1004 public FileDataStorageManager getStorageManager() {
1005 return null;
1006 }
1007
1008 @Override
1009 public FileOperationsHelper getFileOperationsHelper() {
1010 return null;
1011 }
1012
1013 protected ServiceConnection newTransferenceServiceConnection() {
1014 return new PreferencesServiceConnection();
1015 }
1016
1017 /** Defines callbacks for service binding, passed to bindService() */
1018 private class PreferencesServiceConnection implements ServiceConnection {
1019
1020 @Override
1021 public void onServiceConnected(ComponentName component, IBinder service) {
1022
1023 if (component.equals(new ComponentName(Preferences.this, FileDownloader.class))) {
1024 mDownloaderBinder = (FileDownloader.FileDownloaderBinder) service;
1025 } else if (component.equals(new ComponentName(Preferences.this, FileUploader.class))) {
1026 Log_OC.d(TAG, "Upload service connected");
1027 mUploaderBinder = (FileUploader.FileUploaderBinder) service;
1028 }
1029 }
1030
1031 @Override
1032 public void onServiceDisconnected(ComponentName component) {
1033 if (component.equals(new ComponentName(Preferences.this, FileDownloader.class))) {
1034 Log_OC.d(TAG, "Download service suddenly disconnected");
1035 mDownloaderBinder = null;
1036 } else if (component.equals(new ComponentName(Preferences.this, FileUploader.class))) {
1037 Log_OC.d(TAG, "Upload service suddenly disconnected");
1038 mUploaderBinder = null;
1039 }
1040 }
1041 };
1042
1043 /**
1044 *
1045 * Class for loading the version number
1046 *
1047 */
1048 private class LoadingVersionNumberTask extends AsyncTask<Void, Void, Integer> {
1049 protected Integer doInBackground(Void... args) {
1050 try {
1051 URL url = new URL("https://github.com/owncloud/android/raw/beta/apks/latest");
1052 BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
1053
1054 Integer latestVersion = Integer.parseInt(in.readLine());
1055 in.close();
1056
1057 return latestVersion;
1058
1059 } catch (MalformedURLException e) {
1060 e.printStackTrace();
1061 } catch (IOException e) {
1062 e.printStackTrace();
1063 }
1064 return -1;
1065 }
1066 }
1067 }