mirror of
https://github.com/nextcloud/android.git
synced 2024-11-26 23:28:42 +03:00
Merge pull request #1998 from nextcloud/fix-storage-stuff
Fix storage stuff
This commit is contained in:
commit
3f1fb1bbbb
11 changed files with 202 additions and 36 deletions
|
@ -322,7 +322,9 @@ public class PushUtils {
|
|||
FileOutputStream keyFileOutputStream = null;
|
||||
try {
|
||||
if (!new File(path).exists()) {
|
||||
new File(path).createNewFile();
|
||||
File newFile = new File(path);
|
||||
newFile.getParentFile().mkdirs();
|
||||
newFile.createNewFile();
|
||||
}
|
||||
keyFileOutputStream = new FileOutputStream(path);
|
||||
keyFileOutputStream.write(encoded);
|
||||
|
|
|
@ -21,6 +21,7 @@ package com.owncloud.android;
|
|||
|
||||
import android.Manifest;
|
||||
import android.accounts.Account;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
|
@ -33,11 +34,13 @@ import android.content.pm.PackageInfo;
|
|||
import android.content.pm.PackageManager;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.os.StrictMode;
|
||||
import android.support.annotation.StringRes;
|
||||
import android.support.multidex.MultiDexApplication;
|
||||
import android.support.v4.util.Pair;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.text.TextUtils;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.evernote.android.job.JobManager;
|
||||
|
@ -50,6 +53,8 @@ import com.owncloud.android.datamodel.MediaProvider;
|
|||
import com.owncloud.android.datamodel.SyncedFolder;
|
||||
import com.owncloud.android.datamodel.SyncedFolderProvider;
|
||||
import com.owncloud.android.datamodel.ThumbnailsCacheManager;
|
||||
import com.owncloud.android.datastorage.DataStorageProvider;
|
||||
import com.owncloud.android.datastorage.StoragePoint;
|
||||
import com.owncloud.android.db.PreferenceManager;
|
||||
import com.owncloud.android.jobs.NCJobCreator;
|
||||
import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
|
||||
|
@ -99,6 +104,7 @@ public class MainApp extends MultiDexApplication {
|
|||
|
||||
private static boolean mOnlyOnDevice = false;
|
||||
|
||||
private SharedPreferences appPrefs;
|
||||
@SuppressWarnings("unused")
|
||||
private boolean mBound;
|
||||
|
||||
|
@ -112,8 +118,10 @@ public class MainApp extends MultiDexApplication {
|
|||
AnalyticsUtils.disableAnalytics();
|
||||
}
|
||||
|
||||
SharedPreferences appPrefs =
|
||||
PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
|
||||
appPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
|
||||
|
||||
fixStoragePath();
|
||||
|
||||
MainApp.storagePath = appPrefs.getString(Preferences.PreferenceKeys.STORAGE_PATH,
|
||||
getApplicationContext().getFilesDir().getAbsolutePath());
|
||||
|
||||
|
@ -208,13 +216,69 @@ public class MainApp extends MultiDexApplication {
|
|||
|
||||
}
|
||||
|
||||
@SuppressLint("ApplySharedPref") // commit is done on purpose to write immediately
|
||||
private void fixStoragePath() {
|
||||
if (!PreferenceManager.getStoragePathFix(this)) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
StoragePoint[] storagePoints = DataStorageProvider.getInstance().getAvailableStoragePoints();
|
||||
String storagePath = appPrefs.getString(Preferences.PreferenceKeys.STORAGE_PATH, "");
|
||||
if (TextUtils.isEmpty(storagePath)) {
|
||||
if (appPrefs.getInt(WhatsNewActivity.KEY_LAST_SEEN_VERSION_CODE, 0) != 0) {
|
||||
// We already used the app, but no storage is set - fix that!
|
||||
appPrefs.edit().putString(Preferences.PreferenceKeys.STORAGE_PATH,
|
||||
Environment.getExternalStorageDirectory().getAbsolutePath()).commit();
|
||||
appPrefs.edit().remove(PreferenceManager.PREF__KEYS_MIGRATION).commit();
|
||||
} else {
|
||||
// find internal storage path that's indexable
|
||||
boolean set = false;
|
||||
for (StoragePoint storagePoint : storagePoints) {
|
||||
if (storagePoint.getStorageType().equals(StoragePoint.StorageType.INTERNAL) &&
|
||||
storagePoint.getPrivacyType().equals(StoragePoint.PrivacyType.PUBLIC)) {
|
||||
appPrefs.edit().putString(Preferences.PreferenceKeys.STORAGE_PATH,
|
||||
storagePoint.getPath()).commit();
|
||||
appPrefs.edit().remove(PreferenceManager.PREF__KEYS_MIGRATION).commit();
|
||||
set = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!set) {
|
||||
for (StoragePoint storagePoint : storagePoints) {
|
||||
if (storagePoint.getPrivacyType().equals(StoragePoint.PrivacyType.PUBLIC)) {
|
||||
appPrefs.edit().putString(Preferences.PreferenceKeys.STORAGE_PATH,
|
||||
storagePoint.getPath()).commit();
|
||||
appPrefs.edit().remove(PreferenceManager.PREF__KEYS_MIGRATION).commit();
|
||||
set = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
PreferenceManager.setStoragePathFix(this, true);
|
||||
} else {
|
||||
appPrefs.edit().remove(PreferenceManager.PREF__KEYS_MIGRATION).commit();
|
||||
PreferenceManager.setStoragePathFix(this, true);
|
||||
}
|
||||
} else {
|
||||
if (TextUtils.isEmpty(storagePath)) {
|
||||
appPrefs.edit().putString(Preferences.PreferenceKeys.STORAGE_PATH,
|
||||
Environment.getExternalStorageDirectory().getAbsolutePath()).commit();
|
||||
}
|
||||
appPrefs.edit().remove(PreferenceManager.PREF__KEYS_MIGRATION).commit();
|
||||
PreferenceManager.setStoragePathFix(this, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void initAutoUpload() {
|
||||
updateToAutoUpload();
|
||||
cleanOldEntries();
|
||||
updateAutoUploadEntries();
|
||||
|
||||
if (getAppContext() != null) {
|
||||
if (PermissionUtil.checkSelfPermission(getAppContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
|
||||
if (PermissionUtil.checkSelfPermission(getAppContext(),
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
|
||||
splitOutAutoUploadEntries();
|
||||
} else {
|
||||
PreferenceManager.setAutoUploadSplitEntries(getAppContext(), true);
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
package com.owncloud.android.datastorage;
|
||||
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
|
||||
import com.owncloud.android.MainApp;
|
||||
|
@ -31,6 +32,9 @@ import com.owncloud.android.datastorage.providers.MountCommandStoragePointProvid
|
|||
import com.owncloud.android.datastorage.providers.SystemDefaultStoragePointProvider;
|
||||
import com.owncloud.android.datastorage.providers.VDCStoragePointProvider;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
|
@ -62,15 +66,59 @@ public class DataStorageProvider {
|
|||
return mCachedStoragePoints.toArray(new StoragePoint[mCachedStoragePoints.size()]);
|
||||
}
|
||||
|
||||
List<String> paths = new ArrayList<>();
|
||||
StoragePoint storagePoint;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
for (File f : MainApp.getAppContext().getExternalMediaDirs()) {
|
||||
if (f != null && !paths.contains(f.getAbsolutePath())) {
|
||||
storagePoint = new StoragePoint();
|
||||
storagePoint.setPath(f.getAbsolutePath());
|
||||
storagePoint.setDescription(f.getAbsolutePath());
|
||||
storagePoint.setPrivacyType(StoragePoint.PrivacyType.PUBLIC);
|
||||
if (f.getAbsolutePath().startsWith("/storage/emulated/0")) {
|
||||
storagePoint.setStorageType(StoragePoint.StorageType.INTERNAL);
|
||||
mCachedStoragePoints.add(storagePoint);
|
||||
} else {
|
||||
storagePoint.setStorageType(StoragePoint.StorageType.EXTERNAL);
|
||||
if (isExternalStorageWritable()) {
|
||||
mCachedStoragePoints.add(storagePoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (IStoragePointProvider p : mStorageProviders) {
|
||||
if (p.canProvideStoragePoints()) {
|
||||
mCachedStoragePoints.addAll(p.getAvailableStoragePoint());
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < mCachedStoragePoints.size(); i++) {
|
||||
paths.add(mCachedStoragePoints.get(i).getPath());
|
||||
}
|
||||
}
|
||||
|
||||
// Now we go add private ones
|
||||
// Add internal storage directory
|
||||
mCachedStoragePoints.add(new StoragePoint(MainApp.getAppContext().getFilesDir().getAbsolutePath(),
|
||||
MainApp.getAppContext().getFilesDir().getAbsolutePath()));
|
||||
storagePoint = new StoragePoint();
|
||||
storagePoint.setDescription(MainApp.getAppContext().getFilesDir().getAbsolutePath());
|
||||
storagePoint.setPath(MainApp.getAppContext().getFilesDir().getAbsolutePath());
|
||||
storagePoint.setPrivacyType(StoragePoint.PrivacyType.PRIVATE);
|
||||
storagePoint.setStorageType(StoragePoint.StorageType.INTERNAL);
|
||||
if (!paths.contains(MainApp.getAppContext().getFilesDir().getAbsolutePath())) {
|
||||
mCachedStoragePoints.add(storagePoint);
|
||||
}
|
||||
|
||||
// Add external storage directory if available.
|
||||
if (isExternalStorageWritable()) {
|
||||
mCachedStoragePoints.add(new StoragePoint(
|
||||
MainApp.getAppContext().getExternalFilesDir(null).getAbsolutePath(),
|
||||
MainApp.getAppContext().getExternalFilesDir(null).getAbsolutePath()));
|
||||
storagePoint = new StoragePoint();
|
||||
storagePoint.setPath(MainApp.getAppContext().getExternalFilesDir(null).getAbsolutePath());
|
||||
storagePoint.setDescription(MainApp.getAppContext().getExternalFilesDir(null).getAbsolutePath());
|
||||
storagePoint.setPrivacyType(StoragePoint.PrivacyType.PRIVATE);
|
||||
storagePoint.setStorageType(StoragePoint.StorageType.EXTERNAL);
|
||||
if (!paths.contains(MainApp.getAppContext().getExternalFilesDir(null).getAbsolutePath())) {
|
||||
mCachedStoragePoints.add(storagePoint);
|
||||
}
|
||||
}
|
||||
|
||||
return mCachedStoragePoints.toArray(new StoragePoint[mCachedStoragePoints.size()]);
|
||||
|
|
|
@ -25,19 +25,59 @@ package com.owncloud.android.datastorage;
|
|||
* @author Bartosz Przybylski
|
||||
*/
|
||||
public class StoragePoint implements Comparable<StoragePoint> {
|
||||
private String mDescription;
|
||||
private String mPath;
|
||||
|
||||
public StoragePoint(String description, String path) {
|
||||
mDescription = description;
|
||||
mPath = path;
|
||||
public enum StorageType {
|
||||
INTERNAL, EXTERNAL
|
||||
}
|
||||
|
||||
public enum PrivacyType {
|
||||
PRIVATE, PUBLIC
|
||||
}
|
||||
|
||||
private String mDescription;
|
||||
private String mPath;
|
||||
private StorageType mStorageType;
|
||||
private PrivacyType mPrivacyType;
|
||||
|
||||
public StoragePoint() {
|
||||
}
|
||||
|
||||
public StoragePoint(String mDescription, String mPath, StorageType mStorageType, PrivacyType privacyType) {
|
||||
this.mDescription = mDescription;
|
||||
this.mPath = mPath;
|
||||
this.mStorageType = mStorageType;
|
||||
this.mPrivacyType = privacyType;
|
||||
}
|
||||
|
||||
public StorageType getStorageType() {
|
||||
return mStorageType;
|
||||
}
|
||||
|
||||
public PrivacyType getPrivacyType() {
|
||||
return mPrivacyType;
|
||||
}
|
||||
public String getPath() { return mPath; }
|
||||
public String getDescription() { return mDescription; }
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.mDescription = description;
|
||||
}
|
||||
|
||||
public void setPath(String path) {
|
||||
this.mPath = path;
|
||||
}
|
||||
|
||||
public void setStorageType(StorageType storageType) {
|
||||
this.mStorageType = storageType;
|
||||
}
|
||||
|
||||
public void setPrivacyType(PrivacyType privacyType) {
|
||||
this.mPrivacyType = privacyType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(StoragePoint another) {
|
||||
return mPath.compareTo(another.getPath());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -53,7 +53,8 @@ public class EnvironmentStoragePointProvider extends AbstractStoragePointProvide
|
|||
if (env != null) {
|
||||
for (String p : env.split(":")) {
|
||||
if (canBeAddedToAvailableList(result, p)) {
|
||||
result.add(new StoragePoint(p, p));
|
||||
result.add(new StoragePoint(p, p, StoragePoint.StorageType.EXTERNAL,
|
||||
StoragePoint.PrivacyType.PUBLIC));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ public class HardcodedStoragePointProvider extends AbstractStoragePointProvider
|
|||
|
||||
for (String s : PATHS) {
|
||||
if (canBeAddedToAvailableList(result, s)) {
|
||||
result.add(new StoragePoint(s, s));
|
||||
result.add(new StoragePoint(s, s, StoragePoint.StorageType.EXTERNAL, StoragePoint.PrivacyType.PUBLIC));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ public class MountCommandStoragePointProvider extends AbstractCommandLineStorage
|
|||
|
||||
for (String p : getPotentialPaths(getCommandLineResult())) {
|
||||
if (canBeAddedToAvailableList(result, p)) {
|
||||
result.add(new StoragePoint(p, p));
|
||||
result.add(new StoragePoint(p, p, StoragePoint.StorageType.EXTERNAL, StoragePoint.PrivacyType.PUBLIC));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
/**
|
||||
* Nextcloud Android client application
|
||||
* Nextcloud Android client application
|
||||
*
|
||||
* @author Bartosz Przybylski
|
||||
* Copyright (C) 2016 Nextcloud
|
||||
* Copyright (C) 2016 Bartosz Przybylski
|
||||
* @author Bartosz Przybylski
|
||||
* Copyright (C) 2016 Nextcloud
|
||||
* Copyright (C) 2016 Bartosz Przybylski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.owncloud.android.datastorage.providers;
|
||||
|
@ -43,7 +43,8 @@ public class SystemDefaultStoragePointProvider extends AbstractStoragePointProvi
|
|||
final String defaultStringDesc = MainApp.getAppContext().getString(R.string.storage_description_default);
|
||||
// Add private internal storage data directory.
|
||||
result.add(new StoragePoint(defaultStringDesc,
|
||||
MainApp.getAppContext().getFilesDir().getAbsolutePath()));
|
||||
MainApp.getAppContext().getFilesDir().getAbsolutePath(), StoragePoint.StorageType.INTERNAL,
|
||||
StoragePoint.PrivacyType.PRIVATE));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -65,7 +65,8 @@ public class VDCStoragePointProvider extends AbstractCommandLineStoragePoint {
|
|||
final String path = vdcLine[2];
|
||||
|
||||
if (canBeAddedToAvailableList(result, path)) {
|
||||
result.add(new StoragePoint(description, path));
|
||||
result.add(new StoragePoint(description, path, StoragePoint.StorageType.EXTERNAL,
|
||||
StoragePoint.PrivacyType.PRIVATE));
|
||||
}
|
||||
|
||||
} catch (NumberFormatException e) {
|
||||
|
|
|
@ -53,7 +53,8 @@ public abstract class PreferenceManager {
|
|||
private static final String PREF__INSTANT_VIDEO_UPLOAD_PATH_USE_SUBFOLDERS
|
||||
= "instant_video_upload_path_use_subfolders";
|
||||
private static final String PREF__LEGACY_CLEAN = "legacyClean";
|
||||
private static final String PREF__KEYS_MIGRATION = "keysMigration";
|
||||
public static final String PREF__KEYS_MIGRATION = "keysMigration";
|
||||
private static final String PREF__FIX_STORAGE_PATH = "storagePathFix";
|
||||
private static final String PREF__AUTO_UPLOAD_UPDATE_PATH = "autoUploadPathUpdate";
|
||||
private static final String PREF__PUSH_TOKEN = "pushToken";
|
||||
private static final String PREF__AUTO_UPLOAD_SPLIT_OUT = "autoUploadEntriesSplitOut";
|
||||
|
@ -291,6 +292,10 @@ public abstract class PreferenceManager {
|
|||
return getDefaultSharedPreferences(context).getBoolean(PREF__KEYS_MIGRATION, false);
|
||||
}
|
||||
|
||||
public static boolean getStoragePathFix(Context context) {
|
||||
return getDefaultSharedPreferences(context).getBoolean(PREF__FIX_STORAGE_PATH, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the auto upload paths flag last set.
|
||||
|
@ -326,6 +331,10 @@ public abstract class PreferenceManager {
|
|||
saveBooleanPreference(context, PREF__KEYS_MIGRATION, keysMigration);
|
||||
}
|
||||
|
||||
public static void setStoragePathFix(Context context, boolean storagePathFix) {
|
||||
saveBooleanPreference(context, PREF__FIX_STORAGE_PATH, storagePathFix);
|
||||
}
|
||||
|
||||
public static void setAutoUploadInit(Context context, boolean autoUploadInit) {
|
||||
saveBooleanPreference(context, PREF__AUTO_UPLOAD_INIT, autoUploadInit);
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ import com.owncloud.android.utils.ThemeUtils;
|
|||
*/
|
||||
public class WhatsNewActivity extends FragmentActivity implements ViewPager.OnPageChangeListener {
|
||||
|
||||
private static final String KEY_LAST_SEEN_VERSION_CODE = "lastSeenVersionCode";
|
||||
public static final String KEY_LAST_SEEN_VERSION_CODE = "lastSeenVersionCode";
|
||||
|
||||
private static final String SCREEN_NAME = "What's new";
|
||||
|
||||
|
|
Loading…
Reference in a new issue