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