mirror of
https://github.com/etesync/android
synced 2025-03-25 03:45:46 +00:00
Provide settings migration v0.9 -> v1.0
This commit is contained in:
parent
1df3ddbe74
commit
1786b73ac6
@ -9,7 +9,6 @@ package at.bitfire.davdroid;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountManager;
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.ContentProviderClient;
|
||||
@ -19,35 +18,44 @@ import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.PeriodicSync;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.provider.CalendarContract;
|
||||
import android.provider.CalendarContract.Calendars;
|
||||
import android.provider.ContactsContract;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.app.NotificationCompat;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import org.apache.commons.lang3.math.NumberUtils;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import at.bitfire.davdroid.model.ServiceDB;
|
||||
import at.bitfire.davdroid.model.ServiceDB.*;
|
||||
import at.bitfire.davdroid.resource.LocalAddressBook;
|
||||
import at.bitfire.davdroid.resource.LocalCalendar;
|
||||
import at.bitfire.davdroid.resource.LocalTaskList;
|
||||
import at.bitfire.ical4android.CalendarStorageException;
|
||||
import at.bitfire.ical4android.TaskProvider;
|
||||
import at.bitfire.vcard4android.ContactsStorageException;
|
||||
import lombok.Cleanup;
|
||||
import okhttp3.HttpUrl;
|
||||
|
||||
public class AccountSettings {
|
||||
private final static int CURRENT_VERSION = 2;
|
||||
private final static int CURRENT_VERSION = 3;
|
||||
private final static String
|
||||
KEY_SETTINGS_VERSION = "version",
|
||||
|
||||
KEY_USERNAME = "user_name",
|
||||
KEY_AUTH_PREEMPTIVE = "auth_preemptive",
|
||||
KEY_LAST_ANDROID_VERSION = "last_android_version";
|
||||
KEY_USERNAME = "user_name",
|
||||
KEY_AUTH_PREEMPTIVE = "auth_preemptive";
|
||||
|
||||
/* Time range limitation to the past [days]
|
||||
/** Time range limitation to the past [in days]
|
||||
value = null default value (DEFAULT_TIME_RANGE_PAST_DAYS)
|
||||
< 0 (-1) no limit
|
||||
>= 0 entries more than n days in the past won't be synchronized
|
||||
@ -62,7 +70,7 @@ public class AccountSettings {
|
||||
final Account account;
|
||||
|
||||
|
||||
public AccountSettings(Context context, Account account) {
|
||||
public AccountSettings(@NonNull Context context, @NonNull Account account) {
|
||||
this.context = context;
|
||||
this.account = account;
|
||||
|
||||
@ -74,46 +82,25 @@ public class AccountSettings {
|
||||
version = Integer.parseInt(accountManager.getUserData(account, KEY_SETTINGS_VERSION));
|
||||
} catch(NumberFormatException ignored) {
|
||||
}
|
||||
App.log.info("AccountSettings version: v" + version + ", should be: " + version);
|
||||
App.log.info("Account " + account.name + " has version " + version + ", current version: " + CURRENT_VERSION);
|
||||
|
||||
if (version < CURRENT_VERSION) {
|
||||
showNotification(Constants.NOTIFICATION_ACCOUNT_SETTINGS_UPDATED,
|
||||
context.getString(R.string.settings_version_update_title),
|
||||
context.getString(R.string.settings_version_update_description));
|
||||
Notification notify = new NotificationCompat.Builder(context)
|
||||
.setSmallIcon(R.drawable.ic_launcher)
|
||||
.setContentTitle(context.getString(R.string.settings_version_update))
|
||||
.setContentText(context.getString(R.string.settings_version_update_warning))
|
||||
.setCategory(NotificationCompat.CATEGORY_SYSTEM)
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||
.setLocalOnly(true)
|
||||
.build();
|
||||
NotificationManager nm = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
nm.notify(Constants.NOTIFICATION_ACCOUNT_SETTINGS_UPDATED, notify);
|
||||
|
||||
update(version);
|
||||
}
|
||||
|
||||
// check whether Android version has changed
|
||||
String lastAndroidVersionInt = accountManager.getUserData(account, KEY_LAST_ANDROID_VERSION);
|
||||
if (lastAndroidVersionInt != null && NumberUtils.toInt(lastAndroidVersionInt) < Build.VERSION.SDK_INT) {
|
||||
// notify user
|
||||
showNotification(Constants.NOTIFICATION_ANDROID_VERSION_UPDATED,
|
||||
context.getString(R.string.settings_android_update_title),
|
||||
context.getString(R.string.settings_android_update_description));
|
||||
}
|
||||
accountManager.setUserData(account, KEY_LAST_ANDROID_VERSION, String.valueOf(Build.VERSION.SDK_INT));
|
||||
}
|
||||
}
|
||||
|
||||
@TargetApi(21)
|
||||
protected void showNotification(int id, String title, String message) {
|
||||
NotificationManager nm = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
|
||||
Notification.Builder n = new Notification.Builder(context);
|
||||
if (Build.VERSION.SDK_INT >= 16) {
|
||||
n.setPriority(Notification.PRIORITY_HIGH);
|
||||
n.setStyle(new Notification.BigTextStyle().bigText(message));
|
||||
} if (Build.VERSION.SDK_INT >= 20)
|
||||
n.setLocalOnly(true);
|
||||
if (Build.VERSION.SDK_INT >= 21)
|
||||
n.setCategory(Notification.CATEGORY_SYSTEM);
|
||||
n.setSmallIcon(R.drawable.ic_launcher);
|
||||
n.setContentTitle(title);
|
||||
n.setContentText(message);
|
||||
nm.notify(id, Build.VERSION.SDK_INT >= 16 ? n.build() : n.getNotification());
|
||||
}
|
||||
|
||||
|
||||
public static Bundle initialUserData(String userName, boolean preemptive) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString(KEY_SETTINGS_VERSION, String.valueOf(CURRENT_VERSION));
|
||||
@ -126,10 +113,10 @@ public class AccountSettings {
|
||||
// authentication settings
|
||||
|
||||
public String username() { return accountManager.getUserData(account, KEY_USERNAME); }
|
||||
public void username(String userName) { accountManager.setUserData(account, KEY_USERNAME, userName); }
|
||||
public void username(@NonNull String userName) { accountManager.setUserData(account, KEY_USERNAME, userName); }
|
||||
|
||||
public String password() { return accountManager.getPassword(account); }
|
||||
public void password(String password) { accountManager.setPassword(account, password); }
|
||||
public void password(@NonNull String password) { accountManager.setPassword(account, password); }
|
||||
|
||||
public boolean preemptiveAuth() { return Boolean.parseBoolean(accountManager.getUserData(account, KEY_AUTH_PREEMPTIVE)); }
|
||||
public void preemptiveAuth(boolean preemptive) { accountManager.setUserData(account, KEY_AUTH_PREEMPTIVE, Boolean.toString(preemptive)); }
|
||||
@ -137,7 +124,7 @@ public class AccountSettings {
|
||||
|
||||
// sync. settings
|
||||
|
||||
public Long getSyncInterval(String authority) {
|
||||
public Long getSyncInterval(@NonNull String authority) {
|
||||
if (ContentResolver.getIsSyncable(account, authority) <= 0)
|
||||
return null;
|
||||
|
||||
@ -151,7 +138,7 @@ public class AccountSettings {
|
||||
return SYNC_INTERVAL_MANUALLY;
|
||||
}
|
||||
|
||||
public void setSyncInterval(String authority, long seconds) {
|
||||
public void setSyncInterval(@NonNull String authority, long seconds) {
|
||||
if (seconds == SYNC_INTERVAL_MANUALLY) {
|
||||
ContentResolver.setSyncAutomatically(account, authority, false);
|
||||
} else {
|
||||
@ -177,30 +164,19 @@ public class AccountSettings {
|
||||
// update from previous account settings
|
||||
|
||||
private void update(int fromVersion) {
|
||||
for (int toVersion = fromVersion + 1; toVersion <= CURRENT_VERSION; toVersion++)
|
||||
updateTo(toVersion);
|
||||
}
|
||||
|
||||
private void updateTo(int toVersion) {
|
||||
final int fromVersion = toVersion - 1;
|
||||
App.log.info("Updating account settings from v" + fromVersion + " to " + toVersion);
|
||||
try {
|
||||
switch (toVersion) {
|
||||
case 1:
|
||||
update_0_1();
|
||||
break;
|
||||
case 2:
|
||||
update_1_2();
|
||||
break;
|
||||
default:
|
||||
App.log.severe("Don't know how to update settings from v" + fromVersion + " to v" + toVersion);
|
||||
for (int toVersion = fromVersion + 1; toVersion <= CURRENT_VERSION; toVersion++) {
|
||||
App.log.info("Updating account " + account.name + " from version " + fromVersion + " to " + toVersion);
|
||||
try {
|
||||
Method updateProc = getClass().getDeclaredMethod("update_" + fromVersion + "_" + toVersion);
|
||||
updateProc.invoke(this);
|
||||
} catch (Exception e) {
|
||||
App.log.log(Level.SEVERE, "Couldn't update account settings", e);
|
||||
}
|
||||
} catch(Exception e) {
|
||||
App.log.log(Level.SEVERE, "Couldn't update account settings (DAVdroid will probably crash)!", e);
|
||||
}
|
||||
fromVersion = toVersion;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("Recycle")
|
||||
@SuppressWarnings({ "Recycle", "unused" })
|
||||
private void update_0_1() throws URISyntaxException {
|
||||
String v0_principalURL = accountManager.getUserData(account, "principal_url"),
|
||||
v0_addressBookPath = accountManager.getUserData(account, "addressbook_path");
|
||||
@ -244,7 +220,7 @@ public class AccountSettings {
|
||||
accountManager.setUserData(account, KEY_SETTINGS_VERSION, "1");
|
||||
}
|
||||
|
||||
@SuppressWarnings("Recycle")
|
||||
@SuppressWarnings({ "Recycle", "unused" })
|
||||
private void update_1_2() throws ContactsStorageException {
|
||||
/* - KEY_ADDRESSBOOK_URL ("addressbook_url"),
|
||||
- KEY_ADDRESSBOOK_CTAG ("addressbook_ctag"),
|
||||
@ -277,4 +253,117 @@ public class AccountSettings {
|
||||
accountManager.setUserData(account, KEY_SETTINGS_VERSION, "2");
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "Recycle", "unused" })
|
||||
private void update_2_3() {
|
||||
// Don't show a warning for Android updates anymore
|
||||
accountManager.setUserData(account, "last_android_version", null);
|
||||
|
||||
ServiceDB.OpenHelper dbHelper = new ServiceDB.OpenHelper(context);
|
||||
try {
|
||||
SQLiteDatabase db = dbHelper.getWritableDatabase();
|
||||
// we have to create the WebDAV Service database only from the old address book, calendar and task list URLs
|
||||
|
||||
// CardDAV: migrate address books
|
||||
ContentProviderClient client = context.getContentResolver().acquireContentProviderClient(ContactsContract.AUTHORITY);
|
||||
if (client != null)
|
||||
try {
|
||||
LocalAddressBook addrBook = new LocalAddressBook(account, client);
|
||||
String url = addrBook.getURL();
|
||||
if (url != null) {
|
||||
App.log.fine("Migrating address book " + url);
|
||||
|
||||
// insert CardDAV service
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(Services.ACCOUNT_NAME, account.name);
|
||||
values.put(Services.SERVICE, Services.SERVICE_CARDDAV);
|
||||
long service = db.insert(Services._TABLE, null, values);
|
||||
|
||||
// insert address book
|
||||
values.clear();
|
||||
values.put(Collections.SERVICE_ID, service);
|
||||
values.put(Collections.URL, url);
|
||||
values.put(Collections.SYNC, 1);
|
||||
db.insert(Collections._TABLE, null, values);
|
||||
|
||||
// insert home set
|
||||
HttpUrl homeSet = HttpUrl.parse(url).resolve("../");
|
||||
values.clear();
|
||||
values.put(HomeSets.SERVICE_ID, service);
|
||||
values.put(HomeSets.URL, homeSet.toString());
|
||||
db.insert(HomeSets._TABLE, null, values);
|
||||
}
|
||||
} catch (ContactsStorageException e) {
|
||||
App.log.log(Level.SEVERE, "Couldn't migrate address book", e);
|
||||
} finally {
|
||||
client.release();
|
||||
}
|
||||
|
||||
// CalDAV: migrate calendars + task lists
|
||||
Set<String> collections = new HashSet<>();
|
||||
Set<HttpUrl> homeSets = new HashSet<>();
|
||||
|
||||
client = context.getContentResolver().acquireContentProviderClient(CalendarContract.AUTHORITY);
|
||||
if (client != null)
|
||||
try {
|
||||
LocalCalendar calendars[] = (LocalCalendar[])LocalCalendar.find(account, client, LocalCalendar.Factory.INSTANCE, null, null);
|
||||
for (LocalCalendar calendar : calendars) {
|
||||
String url = calendar.getName();
|
||||
App.log.fine("Migrating calendar " + url);
|
||||
collections.add(url);
|
||||
homeSets.add(HttpUrl.parse(url).resolve("../"));
|
||||
}
|
||||
} catch (CalendarStorageException e) {
|
||||
App.log.log(Level.SEVERE, "Couldn't migrate calendars", e);
|
||||
} finally {
|
||||
client.release();
|
||||
}
|
||||
|
||||
TaskProvider provider = LocalTaskList.acquireTaskProvider(context.getContentResolver());
|
||||
if (provider != null)
|
||||
try {
|
||||
LocalTaskList[] taskLists = (LocalTaskList[])LocalTaskList.find(account, provider, LocalTaskList.Factory.INSTANCE, null, null);
|
||||
for (LocalTaskList taskList : taskLists) {
|
||||
String url = taskList.getSyncId();
|
||||
App.log.fine("Migrating task list " + url);
|
||||
collections.add(url);
|
||||
homeSets.add(HttpUrl.parse(url).resolve("../"));
|
||||
}
|
||||
} catch (CalendarStorageException e) {
|
||||
App.log.log(Level.SEVERE, "Couldn't migrate task lists", e);
|
||||
} finally {
|
||||
provider.close();
|
||||
}
|
||||
|
||||
if (!collections.isEmpty()) {
|
||||
// insert CalDAV service
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(Services.ACCOUNT_NAME, account.name);
|
||||
values.put(Services.SERVICE, Services.SERVICE_CALDAV);
|
||||
long service = db.insert(Services._TABLE, null, values);
|
||||
|
||||
// insert collections
|
||||
for (String url : collections) {
|
||||
values.clear();
|
||||
values.put(Collections.SERVICE_ID, service);
|
||||
values.put(Collections.URL, url);
|
||||
values.put(Collections.SYNC, 1);
|
||||
db.insert(Collections._TABLE, null, values);
|
||||
}
|
||||
|
||||
// insert home sets
|
||||
for (HttpUrl homeSet : homeSets) {
|
||||
values.clear();
|
||||
values.put(HomeSets.SERVICE_ID, service);
|
||||
values.put(HomeSets.URL, homeSet.toString());
|
||||
db.insert(HomeSets._TABLE, null, values);
|
||||
}
|
||||
}
|
||||
|
||||
} finally {
|
||||
dbHelper.close();
|
||||
}
|
||||
|
||||
accountManager.setUserData(account, KEY_SETTINGS_VERSION, "3");
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
package at.bitfire.davdroid;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.app.Application;
|
||||
import android.content.SharedPreferences;
|
||||
import android.util.Log;
|
||||
@ -16,6 +17,7 @@ import org.apache.commons.lang3.time.DateFormatUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.logging.FileHandler;
|
||||
import java.util.logging.Handler;
|
||||
import java.util.logging.Level;
|
||||
@ -31,8 +33,8 @@ import okhttp3.internal.tls.OkHostnameVerifier;
|
||||
|
||||
public class App extends Application implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
public static final String
|
||||
PREF_FILE = "davdroid_preferences",
|
||||
PREF_LOG_TO_FILE = "log_to_file";
|
||||
PREF_FILE = "davdroid_preferences", // preference file name
|
||||
PREF_LOG_TO_FILE = "log_to_file"; // boolean: external logging enabled
|
||||
|
||||
@Getter
|
||||
private static MemorizingTrustManager memorizingTrustManager;
|
||||
@ -60,6 +62,7 @@ public class App extends Application implements SharedPreferences.OnSharedPrefer
|
||||
sslSocketFactoryCompat = new SSLSocketFactoryCompat(memorizingTrustManager);
|
||||
hostnameVerifier = memorizingTrustManager.wrapHostnameVerifier(OkHostnameVerifier.INSTANCE);
|
||||
|
||||
// initializer logger
|
||||
reinitLogger();
|
||||
}
|
||||
|
||||
|
@ -43,9 +43,11 @@ public class PlainTextFormatter extends Formatter {
|
||||
builder.append(Log.getStackTraceString(r.getThrown()));
|
||||
}
|
||||
|
||||
if (r.getParameters() != null)
|
||||
if (r.getParameters() != null) {
|
||||
int idx = 1;
|
||||
for (Object param : r.getParameters())
|
||||
builder.append("\nPARAMETER " + param);
|
||||
builder.append("\nPARAMETER #").append(idx).append(" = ").append(param);
|
||||
}
|
||||
|
||||
if (!logcat)
|
||||
builder.append("\n");
|
||||
|
@ -127,7 +127,7 @@ public class CollectionInfo implements Serializable {
|
||||
info.supportsVEVENT = booleanField(values, Collections.SUPPORTS_VEVENT);
|
||||
info.supportsVTODO = booleanField(values, Collections.SUPPORTS_VTODO);
|
||||
|
||||
info.selected = booleanField(values, Collections.SELECTED);
|
||||
info.selected = booleanField(values, Collections.SYNC);
|
||||
return info;
|
||||
}
|
||||
|
||||
@ -146,7 +146,7 @@ public class CollectionInfo implements Serializable {
|
||||
if (supportsVTODO != null)
|
||||
values.put(Collections.SUPPORTS_VTODO, supportsVTODO ? 1 : 0);
|
||||
|
||||
values.put(Collections.SELECTED, selected ? 1 : 0);
|
||||
values.put(Collections.SYNC, selected ? 1 : 0);
|
||||
return values;
|
||||
}
|
||||
|
||||
|
@ -54,12 +54,12 @@ public class ServiceDB {
|
||||
TIME_ZONE = "timezone",
|
||||
SUPPORTS_VEVENT = "supportsVEVENT",
|
||||
SUPPORTS_VTODO = "supportsVTODO",
|
||||
SELECTED = "selected";
|
||||
SYNC = "sync";
|
||||
|
||||
public static String[] _COLUMNS = new String[] {
|
||||
ID, SERVICE_ID, URL, DISPLAY_NAME, DESCRIPTION, COLOR,
|
||||
TIME_ZONE, SUPPORTS_VEVENT, SUPPORTS_VTODO,
|
||||
SELECTED
|
||||
SYNC
|
||||
};
|
||||
}
|
||||
|
||||
@ -110,7 +110,7 @@ public class ServiceDB {
|
||||
Collections.TIME_ZONE + " TEXt NULL," +
|
||||
Collections.SUPPORTS_VEVENT + " INTEGER NULL," +
|
||||
Collections.SUPPORTS_VTODO + " INTEGER NULL," +
|
||||
Collections.SELECTED + " INTEGER DEFAULT 0 NOT NULL" +
|
||||
Collections.SYNC + " INTEGER DEFAULT 0 NOT NULL" +
|
||||
")");
|
||||
db.execSQL("CREATE UNIQUE INDEX collections_service_url ON " + Collections._TABLE + "(" + Collections.SERVICE_ID + "," + Collections.URL + ")");
|
||||
}
|
||||
|
@ -21,6 +21,9 @@ import android.database.sqlite.SQLiteDatabase;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import at.bitfire.davdroid.App;
|
||||
import at.bitfire.davdroid.model.CollectionInfo;
|
||||
@ -65,25 +68,30 @@ public class ContactsSyncAdapterService extends Service {
|
||||
// required for dav4android (ServiceLoader)
|
||||
Thread.currentThread().setContextClassLoader(getContext().getClassLoader());
|
||||
|
||||
long service = getService(account);
|
||||
CollectionInfo remote = remoteAddressBook(service);
|
||||
|
||||
if (remote != null) {
|
||||
ContactsSyncManager syncManager = new ContactsSyncManager(getContext(), account, extras, authority, provider, syncResult, remote);
|
||||
syncManager.performSync();
|
||||
} else
|
||||
App.log.info("No address book collection selected for synchronization");
|
||||
Long service = getService(account);
|
||||
if (service != null) {
|
||||
CollectionInfo remote = remoteAddressBook(service);
|
||||
if (remote != null) {
|
||||
ContactsSyncManager syncManager = new ContactsSyncManager(getContext(), account, extras, authority, provider, syncResult, remote);
|
||||
syncManager.performSync();
|
||||
} else
|
||||
App.log.info("No address book collection selected for synchronization");
|
||||
}
|
||||
|
||||
App.log.info("Address book sync complete");
|
||||
}
|
||||
|
||||
private long getService(@NonNull Account account) {
|
||||
@Nullable
|
||||
private Long getService(@NonNull Account account) {
|
||||
@Cleanup Cursor c = db.query(ServiceDB.Services._TABLE, new String[] { ServiceDB.Services.ID },
|
||||
ServiceDB.Services.ACCOUNT_NAME + "=? AND " + ServiceDB.Services.SERVICE + "=?", new String[] { account.name, ServiceDB.Services.SERVICE_CARDDAV }, null, null, null);
|
||||
c.moveToNext();
|
||||
return c.getLong(0);
|
||||
if (c.moveToNext())
|
||||
return c.getLong(0);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private CollectionInfo remoteAddressBook(long service) {
|
||||
@Cleanup Cursor c = db.query(Collections._TABLE, Collections._COLUMNS,
|
||||
Collections.SERVICE_ID + "=? AND selected", new String[] { String.valueOf(service) }, null, null, null);
|
||||
|
@ -62,7 +62,9 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import at.bitfire.davdroid.AccountSettings;
|
||||
import at.bitfire.davdroid.App;
|
||||
import at.bitfire.davdroid.Constants;
|
||||
import at.bitfire.davdroid.DavService;
|
||||
import at.bitfire.davdroid.R;
|
||||
import at.bitfire.davdroid.model.CollectionInfo;
|
||||
@ -199,12 +201,12 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
|
||||
if (list.getChoiceMode() == AbsListView.CHOICE_MODE_SINGLE) {
|
||||
// disable all other collections
|
||||
ContentValues values = new ContentValues(1);
|
||||
values.put(Collections.SELECTED, 0);
|
||||
values.put(Collections.SYNC, 0);
|
||||
db.update(Collections._TABLE, values, Collections.SERVICE_ID + "=?", new String[] { String.valueOf(info.serviceID) });
|
||||
}
|
||||
|
||||
ContentValues values = new ContentValues(1);
|
||||
values.put(Collections.SELECTED, nowChecked ? 1 : 0);
|
||||
values.put(Collections.SYNC, nowChecked ? 1 : 0);
|
||||
db.update(Collections._TABLE, values, Collections.ID + "=?", new String[] { String.valueOf(info.id) });
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
@ -314,8 +316,11 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(Loader<AccountInfo> loader) {
|
||||
listCardDAV.setAdapter(null);
|
||||
listCalDAV.setAdapter(null);
|
||||
if (listCardDAV != null)
|
||||
listCardDAV.setAdapter(null);
|
||||
|
||||
if (listCalDAV != null)
|
||||
listCalDAV.setAdapter(null);
|
||||
}
|
||||
|
||||
|
||||
@ -361,6 +366,11 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
|
||||
|
||||
@Override
|
||||
public AccountInfo loadInBackground() {
|
||||
// peek into AccountSettings to call possible 0.9 -> 1.0 migration
|
||||
// The next line can be removed as soon as migration from 0.9 is not required anymore!
|
||||
new AccountSettings(getContext(), new Account(accountName, Constants.ACCOUNT_TYPE));
|
||||
|
||||
// get account info
|
||||
AccountInfo info = new AccountInfo();
|
||||
try {
|
||||
SQLiteDatabase db = dbHelper.getReadableDatabase();
|
||||
|
@ -27,6 +27,7 @@ import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import at.bitfire.davdroid.App;
|
||||
import at.bitfire.davdroid.BuildConfig;
|
||||
import at.bitfire.davdroid.Constants;
|
||||
import at.bitfire.davdroid.R;
|
||||
import at.bitfire.davdroid.resource.LocalTaskList;
|
||||
@ -39,24 +40,28 @@ public class StartupDialogFragment extends DialogFragment {
|
||||
private static final String ARGS_MODE = "mode";
|
||||
|
||||
enum Mode {
|
||||
DEVELOPMENT_VERSION,
|
||||
FDROID_DONATE,
|
||||
GOOGLE_PLAY_ACCOUNTS_REMOVED,
|
||||
OPENTASKS_NOT_INSTALLED
|
||||
}
|
||||
|
||||
|
||||
public static StartupDialogFragment[] getStartupDialogs(Context context) {
|
||||
List<StartupDialogFragment> dialogs = new LinkedList<>();
|
||||
|
||||
// store-specific information
|
||||
final String installedFrom = installedFrom(context);
|
||||
if (installedFrom == null || installedFrom.startsWith("org.fdroid"))
|
||||
dialogs.add(StartupDialogFragment.instantiate(Mode.FDROID_DONATE));
|
||||
if (BuildConfig.VERSION_NAME.contains("-alpha") || BuildConfig.VERSION_NAME.contains("-beta"))
|
||||
dialogs.add(StartupDialogFragment.instantiate(Mode.DEVELOPMENT_VERSION));
|
||||
else {
|
||||
// store-specific information
|
||||
final String installedFrom = installedFrom(context);
|
||||
if (installedFrom == null || installedFrom.startsWith("org.fdroid"))
|
||||
dialogs.add(StartupDialogFragment.instantiate(Mode.FDROID_DONATE));
|
||||
|
||||
else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP && // only on Android <5
|
||||
"com.android.vending".equals(installedFrom) && // only when installed from Play Store
|
||||
App.getPreferences().getBoolean(PREF_HINT_GOOGLE_PLAY_ACCOUNTS_REMOVED, true)) // and only when "Don't show again" hasn't been clicked yet
|
||||
dialogs.add(StartupDialogFragment.instantiate(Mode.GOOGLE_PLAY_ACCOUNTS_REMOVED));
|
||||
else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP && // only on Android <5
|
||||
"com.android.vending".equals(installedFrom) && // only when installed from Play Store
|
||||
App.getPreferences().getBoolean(PREF_HINT_GOOGLE_PLAY_ACCOUNTS_REMOVED, true)) // and only when "Don't show again" hasn't been clicked yet
|
||||
dialogs.add(StartupDialogFragment.instantiate(Mode.GOOGLE_PLAY_ACCOUNTS_REMOVED));
|
||||
}
|
||||
|
||||
// OpenTasks information
|
||||
if (!LocalTaskList.tasksProviderAvailable(context.getContentResolver()) &&
|
||||
@ -82,6 +87,24 @@ public class StartupDialogFragment extends DialogFragment {
|
||||
|
||||
Mode mode = Mode.valueOf(getArguments().getString(ARGS_MODE));
|
||||
switch (mode) {
|
||||
case DEVELOPMENT_VERSION:
|
||||
return new AlertDialog.Builder(getActivity())
|
||||
.setIcon(R.drawable.ic_launcher)
|
||||
.setTitle(R.string.startup_development_version)
|
||||
.setMessage(R.string.startup_development_version_message)
|
||||
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
}
|
||||
})
|
||||
.setNeutralButton(R.string.startup_development_version_show_forums, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
startActivity(new Intent(Intent.ACTION_VIEW, Constants.webUri.buildUpon().appendEncodedPath("forums/").build()));
|
||||
}
|
||||
})
|
||||
.create();
|
||||
|
||||
case FDROID_DONATE:
|
||||
return new AlertDialog.Builder(getActivity())
|
||||
.setIcon(R.drawable.ic_launcher)
|
||||
|
@ -19,6 +19,10 @@
|
||||
|
||||
<!-- startup dialogs -->
|
||||
<string name="startup_dont_show_again">Don\'t show again</string>
|
||||
<string name="startup_development_version">DAVdroid Preview Release</string>
|
||||
<string name="startup_development_version_message">This is a development version of DAVdroid. Be aware that things
|
||||
may not work as expected. Please give us constructive feedback to improve DAVdroid.</string>
|
||||
<string name="startup_development_version_show_forums">Show forums</string>
|
||||
<string name="startup_donate">Open-Source Information</string>
|
||||
<string name="startup_donate_message">We\'re happy that you use DAVdroid, which is open-source software (GPLv3). Because developing DAVdroid is hard work and took us thousands of working hours, please consider a donation.</string>
|
||||
<string name="startup_donate_now">Show donation page</string>
|
||||
@ -147,6 +151,8 @@
|
||||
<item quantity="other">Events more than %d days in the past will be ignored</item>
|
||||
</plurals>
|
||||
<string name="settings_sync_time_range_past_message">Events which are more than this number of days in the past (may be 0) will be ignored. Leave blank to synchronize all events.</string>
|
||||
<string name="settings_version_update">DAVdroid version update</string>
|
||||
<string name="settings_version_update_warning">Internal settings have been updated. In case of problems, please uninstall DAVdroid and then install it again.</string>
|
||||
|
||||
<!-- collection management -->
|
||||
<string name="create_addressbook">Create address book</string>
|
||||
@ -175,11 +181,6 @@
|
||||
<string name="exception_ioexception">An I/O error has occurred.</string>
|
||||
<string name="exception_show_details">Show details</string>
|
||||
|
||||
<string name="settings_android_update_title">Android version update</string>
|
||||
<string name="settings_android_update_description">Android version updates may have an impact on how DAVdroid works. If there are problems, please delete your DAVdroid accounts and add them again.</string>
|
||||
<string name="settings_version_update_title">Settings have been updated</string>
|
||||
<string name="settings_version_update_description">Internal settings have been updated. If there are problems, please uninstall DAVdroid and then install it again.</string>
|
||||
|
||||
<!-- sync errors and DebugInfoActivity -->
|
||||
<string name="debug_info_title">Debug info</string>
|
||||
<string name="sync_error_calendar">Calendar synchronization failed (%s)</string>
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 5e7334cea2bbaacde7f61b9806c907ba7404753d
|
||||
Subproject commit 0532282932b71209000e158dd9e6a1725c58b117
|
Loading…
Reference in New Issue
Block a user