From 3813c1e0c805660f41f5239ebf64035d918b53a7 Mon Sep 17 00:00:00 2001 From: Ricki Hirner Date: Tue, 4 Oct 2016 16:12:44 +0200 Subject: [PATCH] Android 4.0/4.1 fixes * require API level 15 for TransactionTooLargeException * use SQLite WAL only on API level 16+ * various database access, provider access and UI fixes --- app/build.gradle | 8 +-- .../at/bitfire/davdroid/model/ServiceDB.java | 23 ++++--- .../davdroid/resource/LocalCalendar.java | 9 +-- .../bitfire/davdroid/resource/LocalEvent.java | 8 ++- .../syncadapter/SyncAdapterService.java | 4 +- .../bitfire/davdroid/ui/AccountActivity.java | 68 +++++++++---------- .../davdroid/ui/AppSettingsActivity.java | 1 - .../davdroid/ui/StartupDialogFragment.java | 5 +- .../ui/setup/LoginCredentialsFragment.java | 1 - app/src/main/res/menu/activity_account.xml | 5 +- ical4android | 2 +- vcard4android | 2 +- 12 files changed, 67 insertions(+), 69 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 0a6a582e..37818291 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -10,14 +10,14 @@ apply plugin: 'com.android.application' android { compileSdkVersion 24 - buildToolsVersion '24.0.2' + buildToolsVersion '24.0.3' defaultConfig { applicationId "at.bitfire.davdroid" - minSdkVersion 14 + minSdkVersion 15 targetSdkVersion 24 - versionCode 118 + versionCode 119 buildConfigField "long", "buildTime", System.currentTimeMillis() + "L" buildConfigField "boolean", "customCerts", "true" @@ -25,7 +25,7 @@ android { productFlavors { standard { - versionName "1.3.2-ose" + versionName "1.3.2.1-ose" } } diff --git a/app/src/main/java/at/bitfire/davdroid/model/ServiceDB.java b/app/src/main/java/at/bitfire/davdroid/model/ServiceDB.java index 9e689435..9b3a5ab6 100644 --- a/app/src/main/java/at/bitfire/davdroid/model/ServiceDB.java +++ b/app/src/main/java/at/bitfire/davdroid/model/ServiceDB.java @@ -14,7 +14,11 @@ import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteException; import android.database.sqlite.SQLiteOpenHelper; import android.os.Build; +import android.support.annotation.RequiresApi; +import java.util.logging.Level; + +import aQute.service.reporter.Messages; import at.bitfire.davdroid.App; import lombok.Cleanup; @@ -72,21 +76,19 @@ public class ServiceDB { public OpenHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) - setWriteAheadLoggingEnabled(true); } @Override public void onOpen(SQLiteDatabase db) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) - db.setForeignKeyConstraintsEnabled(true); - else { - if (!db.enableWriteAheadLogging()) - App.log.warning("Couldn't enable write-ahead logging"); - + if (Build.VERSION.SDK_INT < 16) db.execSQL("PRAGMA foreign_keys=ON;"); - } + } + + @Override + @RequiresApi(16) + public void onConfigure(SQLiteDatabase db) { + setWriteAheadLoggingEnabled(true); + db.setForeignKeyConstraintsEnabled(true); } @Override @@ -132,6 +134,7 @@ public class ServiceDB { @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { + // no different versions yet } diff --git a/app/src/main/java/at/bitfire/davdroid/resource/LocalCalendar.java b/app/src/main/java/at/bitfire/davdroid/resource/LocalCalendar.java index 714b274e..d76a70f8 100644 --- a/app/src/main/java/at/bitfire/davdroid/resource/LocalCalendar.java +++ b/app/src/main/java/at/bitfire/davdroid/resource/LocalCalendar.java @@ -9,14 +9,12 @@ package at.bitfire.davdroid.resource; import android.accounts.Account; -import android.annotation.TargetApi; import android.content.ContentProviderClient; import android.content.ContentProviderOperation; import android.content.ContentUris; import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; -import android.os.Build; import android.os.RemoteException; import android.provider.CalendarContract; import android.provider.CalendarContract.Calendars; @@ -85,7 +83,6 @@ public class LocalCalendar extends AndroidCalendar implements LocalCollection { update(valuesFromCollectionInfo(info, updateColor)); } - @TargetApi(15) private static ContentValues valuesFromCollectionInfo(CollectionInfo info, boolean withColor) { ContentValues values = new ContentValues(); values.put(Calendars.NAME, info.url); @@ -108,10 +105,8 @@ public class LocalCalendar extends AndroidCalendar implements LocalCollection { values.put(Calendars.CALENDAR_TIME_ZONE, DateUtils.findAndroidTimezoneID(timeZone.getTimeZoneId().getValue())); } values.put(Calendars.ALLOWED_REMINDERS, Reminders.METHOD_ALERT); - if (Build.VERSION.SDK_INT >= 15) { - values.put(Calendars.ALLOWED_AVAILABILITY, StringUtils.join(new int[] { Reminders.AVAILABILITY_TENTATIVE, Reminders.AVAILABILITY_FREE, Reminders.AVAILABILITY_BUSY }, ",")); - values.put(Calendars.ALLOWED_ATTENDEE_TYPES, StringUtils.join(new int[] { CalendarContract.Attendees.TYPE_OPTIONAL, CalendarContract.Attendees.TYPE_REQUIRED, CalendarContract.Attendees.TYPE_RESOURCE }, ", ")); - } + values.put(Calendars.ALLOWED_AVAILABILITY, StringUtils.join(new int[] { Reminders.AVAILABILITY_TENTATIVE, Reminders.AVAILABILITY_FREE, Reminders.AVAILABILITY_BUSY }, ",")); + values.put(Calendars.ALLOWED_ATTENDEE_TYPES, StringUtils.join(new int[] { CalendarContract.Attendees.TYPE_OPTIONAL, CalendarContract.Attendees.TYPE_REQUIRED, CalendarContract.Attendees.TYPE_RESOURCE }, ", ")); return values; } diff --git a/app/src/main/java/at/bitfire/davdroid/resource/LocalEvent.java b/app/src/main/java/at/bitfire/davdroid/resource/LocalEvent.java index d2617c72..858d8d20 100644 --- a/app/src/main/java/at/bitfire/davdroid/resource/LocalEvent.java +++ b/app/src/main/java/at/bitfire/davdroid/resource/LocalEvent.java @@ -68,8 +68,12 @@ public class LocalEvent extends AndroidEvent implements LocalResource { event.uid = values.getAsString(COLUMN_UID); event.sequence = values.getAsInteger(COLUMN_SEQUENCE); - if (values.getAsInteger(Events.IS_ORGANIZER) == 0) - weAreOrganizer = false; + if (Build.VERSION.SDK_INT >= 17) + weAreOrganizer = values.getAsInteger(Events.IS_ORGANIZER) != 0; + else { + String organizer = values.getAsString(Events.ORGANIZER); + weAreOrganizer = organizer == null || organizer.equals(calendar.account.name); + } } @Override diff --git a/app/src/main/java/at/bitfire/davdroid/syncadapter/SyncAdapterService.java b/app/src/main/java/at/bitfire/davdroid/syncadapter/SyncAdapterService.java index 5e551883..34a1ce21 100644 --- a/app/src/main/java/at/bitfire/davdroid/syncadapter/SyncAdapterService.java +++ b/app/src/main/java/at/bitfire/davdroid/syncadapter/SyncAdapterService.java @@ -10,7 +10,6 @@ package at.bitfire.davdroid.syncadapter; import android.accounts.Account; import android.app.Notification; -import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.AbstractThreadedSyncAdapter; @@ -18,7 +17,6 @@ import android.content.ContentProviderClient; import android.content.Context; import android.content.Intent; import android.content.SyncResult; -import android.graphics.drawable.BitmapDrawable; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.wifi.WifiInfo; @@ -38,6 +36,8 @@ import at.bitfire.davdroid.Constants; import at.bitfire.davdroid.R; import at.bitfire.davdroid.ui.PermissionsActivity; +//import com.android.vending.billing.IInAppBillingService; + public abstract class SyncAdapterService extends Service { abstract protected AbstractThreadedSyncAdapter syncAdapter(); diff --git a/app/src/main/java/at/bitfire/davdroid/ui/AccountActivity.java b/app/src/main/java/at/bitfire/davdroid/ui/AccountActivity.java index 376513e8..8b7cf8a7 100644 --- a/app/src/main/java/at/bitfire/davdroid/ui/AccountActivity.java +++ b/app/src/main/java/at/bitfire/davdroid/ui/AccountActivity.java @@ -355,14 +355,12 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu private static class AccountLoader extends AsyncTaskLoader implements DavService.RefreshingStatusListener, ServiceConnection, SyncStatusObserver { private final Account account; - private final OpenHelper dbHelper; private DavService.InfoBinder davService; private Object syncStatusListener; public AccountLoader(Context context, Account account) { super(context); this.account = account; - dbHelper = new OpenHelper(context); } @Override @@ -407,41 +405,39 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu @Override public AccountInfo loadInBackground() { AccountInfo info = new AccountInfo(); - try { - SQLiteDatabase db = dbHelper.getReadableDatabase(); - - @Cleanup Cursor cursor = db.query( - Services._TABLE, - new String[] { Services.ID, Services.SERVICE }, - Services.ACCOUNT_NAME + "=?", new String[] { account.name }, - null, null, null); - - if (cursor.getCount() == 0) - // no services, account not useable - return null; - - while (cursor.moveToNext()) { - long id = cursor.getLong(0); - String service = cursor.getString(1); - if (Services.SERVICE_CARDDAV.equals(service)) { - info.carddav = new AccountInfo.ServiceInfo(); - info.carddav.id = id; - info.carddav.refreshing = davService.isRefreshing(id) || ContentResolver.isSyncActive(account, ContactsContract.AUTHORITY); - info.carddav.hasHomeSets = hasHomeSets(db, id); - info.carddav.collections = readCollections(db, id); - - } else if (Services.SERVICE_CALDAV.equals(service)) { - info.caldav = new AccountInfo.ServiceInfo(); - info.caldav.id = id; - info.caldav.refreshing = davService.isRefreshing(id) || - ContentResolver.isSyncActive(account, CalendarContract.AUTHORITY) || - ContentResolver.isSyncActive(account, TaskProvider.ProviderName.OpenTasks.authority); - info.caldav.hasHomeSets = hasHomeSets(db, id); - info.caldav.collections = readCollections(db, id); - } + + @Cleanup OpenHelper dbHelper = new OpenHelper(getContext()); + SQLiteDatabase db = dbHelper.getReadableDatabase(); + + @Cleanup Cursor cursor = db.query( + Services._TABLE, + new String[] { Services.ID, Services.SERVICE }, + Services.ACCOUNT_NAME + "=?", new String[] { account.name }, + null, null, null); + + if (cursor.getCount() == 0) + // no services, account not useable + return null; + + while (cursor.moveToNext()) { + long id = cursor.getLong(0); + String service = cursor.getString(1); + if (Services.SERVICE_CARDDAV.equals(service)) { + info.carddav = new AccountInfo.ServiceInfo(); + info.carddav.id = id; + info.carddav.refreshing = davService.isRefreshing(id) || ContentResolver.isSyncActive(account, ContactsContract.AUTHORITY); + info.carddav.hasHomeSets = hasHomeSets(db, id); + info.carddav.collections = readCollections(db, id); + + } else if (Services.SERVICE_CALDAV.equals(service)) { + info.caldav = new AccountInfo.ServiceInfo(); + info.caldav.id = id; + info.caldav.refreshing = davService.isRefreshing(id) || + ContentResolver.isSyncActive(account, CalendarContract.AUTHORITY) || + ContentResolver.isSyncActive(account, TaskProvider.ProviderName.OpenTasks.authority); + info.caldav.hasHomeSets = hasHomeSets(db, id); + info.caldav.collections = readCollections(db, id); } - } finally { - dbHelper.close(); } return info; } diff --git a/app/src/main/java/at/bitfire/davdroid/ui/AppSettingsActivity.java b/app/src/main/java/at/bitfire/davdroid/ui/AppSettingsActivity.java index 45acf020..41153c0b 100644 --- a/app/src/main/java/at/bitfire/davdroid/ui/AppSettingsActivity.java +++ b/app/src/main/java/at/bitfire/davdroid/ui/AppSettingsActivity.java @@ -20,7 +20,6 @@ import at.bitfire.davdroid.App; import at.bitfire.davdroid.R; import at.bitfire.davdroid.model.ServiceDB; import at.bitfire.davdroid.model.Settings; -import lombok.Cleanup; public class AppSettingsActivity extends AppCompatActivity { diff --git a/app/src/main/java/at/bitfire/davdroid/ui/StartupDialogFragment.java b/app/src/main/java/at/bitfire/davdroid/ui/StartupDialogFragment.java index b4f0f047..814026dc 100644 --- a/app/src/main/java/at/bitfire/davdroid/ui/StartupDialogFragment.java +++ b/app/src/main/java/at/bitfire/davdroid/ui/StartupDialogFragment.java @@ -15,6 +15,7 @@ import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; +import android.database.sqlite.SQLiteDatabase; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Build; @@ -95,8 +96,6 @@ public class StartupDialogFragment extends DialogFragment { public Dialog onCreateDialog(Bundle savedInstanceState) { setCancelable(false); - final ServiceDB.OpenHelper dbHelper = new ServiceDB.OpenHelper(getContext()); - Mode mode = Mode.valueOf(getArguments().getString(ARGS_MODE)); switch (mode) { case BATTERY_OPTIMIZATIONS: @@ -119,6 +118,7 @@ public class StartupDialogFragment extends DialogFragment { .setNegativeButton(R.string.startup_dont_show_again, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { + @Cleanup ServiceDB.OpenHelper dbHelper = new ServiceDB.OpenHelper(getContext()); Settings settings = new Settings(dbHelper.getWritableDatabase()); settings.putBoolean(HINT_BATTERY_OPTIMIZATIONS, false); } @@ -187,6 +187,7 @@ public class StartupDialogFragment extends DialogFragment { .setNegativeButton(R.string.startup_dont_show_again, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { + @Cleanup ServiceDB.OpenHelper dbHelper = new ServiceDB.OpenHelper(getContext()); Settings settings = new Settings(dbHelper.getWritableDatabase()); settings.putBoolean(HINT_OPENTASKS_NOT_INSTALLED, false); } diff --git a/app/src/main/java/at/bitfire/davdroid/ui/setup/LoginCredentialsFragment.java b/app/src/main/java/at/bitfire/davdroid/ui/setup/LoginCredentialsFragment.java index 5781b99a..48fc2194 100644 --- a/app/src/main/java/at/bitfire/davdroid/ui/setup/LoginCredentialsFragment.java +++ b/app/src/main/java/at/bitfire/davdroid/ui/setup/LoginCredentialsFragment.java @@ -17,7 +17,6 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; -import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.EditText; import android.widget.LinearLayout; diff --git a/app/src/main/res/menu/activity_account.xml b/app/src/main/res/menu/activity_account.xml index 8a7e428f..d591ff6f 100644 --- a/app/src/main/res/menu/activity_account.xml +++ b/app/src/main/res/menu/activity_account.xml @@ -13,7 +13,7 @@ + app:showAsAction="always"/> + android:title="@string/account_delete" + app:showAsAction="never"/> \ No newline at end of file diff --git a/ical4android b/ical4android index f6535874..85f4d947 160000 --- a/ical4android +++ b/ical4android @@ -1 +1 @@ -Subproject commit f6535874a9f1f399913dcb51bda1aa9affbb4c5a +Subproject commit 85f4d947089ac3e0b7a61cbedfc69dd6ec7f235d diff --git a/vcard4android b/vcard4android index 8c4776a6..95a27610 160000 --- a/vcard4android +++ b/vcard4android @@ -1 +1 @@ -Subproject commit 8c4776a6be83b641611c12e1a0e524b6435bcf9a +Subproject commit 95a2761006f1c605ee277fa36b0d1aaa083c86bc