diff --git a/.travis.yml b/.travis.yml index 077b96a6f..7d335b5f8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,8 +2,8 @@ language: android android: components: - tools - - build-tools-26.0.2 - - android-26 + - build-tools-28.0.3 + - android-28 jdk: oraclejdk8 diff --git a/app/build.gradle b/app/build.gradle index 8603de570..a4163d509 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -7,12 +7,12 @@ if (keystorePropertiesFile.exists()) { } android { - compileSdkVersion 25 - buildToolsVersion "26.0.2" + compileSdkVersion 28 + buildToolsVersion "28.0.3" defaultConfig { applicationId "com.zegoggles.smssync" - minSdkVersion 9 - targetSdkVersion 25 + minSdkVersion 14 + targetSdkVersion 28 versionCode 1576 versionName "1.5.11" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" @@ -53,21 +53,21 @@ android { } dependencies { - compile 'com.squareup:otto:1.3.8' - compile 'com.github.jberkel.k-9:k9mail-library:eaf689025e' - compile 'com.android.billingclient:billing:1.0' - compile 'com.firebase:firebase-jobdispatcher:0.8.5' - compile 'com.android.support:support-annotations:25.3.1' - compile 'com.android.support:preference-v7:25.3.1' + implementation 'com.squareup:otto:1.3.8' + implementation 'com.github.jberkel.k-9:k9mail-library:eaf689025e' + implementation 'com.android.billingclient:billing:1.0' + implementation 'com.firebase:firebase-jobdispatcher:0.8.5' + implementation 'com.android.support:support-annotations:28.0.0' + implementation 'com.android.support:preference-v7:28.0.0' - testCompile 'junit:junit:4.12' - testCompile 'org.robolectric:robolectric:3.6.1' - testCompile "com.google.truth:truth:0.39" - testCompile 'org.mockito:mockito-all:1.10.17' + testImplementation 'junit:junit:4.12' + testImplementation 'org.robolectric:robolectric:3.6.1' + testImplementation "com.google.truth:truth:0.39" + testImplementation 'org.mockito:mockito-all:1.10.17' } tasks.withType(JavaCompile) { if (!it.name.toLowerCase().contains('test')) { - options.compilerArgs = ['-Werror', '-Xlint:unchecked', '-Xlint:deprecation'] + options.compilerArgs = ['-Werror', '-Xlint:unchecked', '-Xlint:deprecation'] } } diff --git a/app/lint.xml b/app/lint.xml index 0ff004bb3..eab301f8b 100644 --- a/app/lint.xml +++ b/app/lint.xml @@ -1,5 +1,6 @@ + diff --git a/app/src/main/java/com/zegoggles/smssync/App.java b/app/src/main/java/com/zegoggles/smssync/App.java index d46e8baa7..7cd630e98 100644 --- a/app/src/main/java/com/zegoggles/smssync/App.java +++ b/app/src/main/java/com/zegoggles/smssync/App.java @@ -24,7 +24,6 @@ import android.content.pm.PackageManager; import android.database.ContentObserver; import android.net.Uri; -import android.os.Build; import android.os.Handler; import android.os.StrictMode; import android.support.annotation.Nullable; @@ -132,6 +131,7 @@ public static String getVersionName(Context context) { } } + @SuppressWarnings("deprecation") public static int getVersionCode(Context context) { PackageInfo pInfo; try { @@ -183,14 +183,12 @@ private void rescheduleJobs() { } private void setupStrictMode() { - if (BuildConfig.DEBUG && Build.VERSION.SDK_INT >= 11) { - StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() + StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() // .detectDiskReads() - .detectDiskWrites() - .detectNetwork() - .penaltyFlashScreen() - .build()); - } + .detectDiskWrites() + .detectNetwork() + .penaltyFlashScreen() + .build()); } private static class LoggingContentObserver extends ContentObserver { diff --git a/app/src/main/java/com/zegoggles/smssync/activity/Dialogs.java b/app/src/main/java/com/zegoggles/smssync/activity/Dialogs.java index 49e9bf641..10d061964 100644 --- a/app/src/main/java/com/zegoggles/smssync/activity/Dialogs.java +++ b/app/src/main/java/com/zegoggles/smssync/activity/Dialogs.java @@ -17,7 +17,6 @@ import android.annotation.SuppressLint; import android.app.Dialog; -import android.app.ProgressDialog; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; @@ -49,7 +48,6 @@ import static android.R.string.cancel; import static android.R.string.ok; import static android.R.string.yes; -import static android.app.ProgressDialog.STYLE_SPINNER; import static android.content.DialogInterface.BUTTON_NEGATIVE; import static com.zegoggles.smssync.activity.MainActivity.REQUEST_CHANGE_DEFAULT_SMS_PACKAGE; import static com.zegoggles.smssync.activity.MainActivity.REQUEST_WEB_AUTH; @@ -224,13 +222,14 @@ public void onClick(DialogInterface dialog, int which) { } public static class AccessTokenProgress extends BaseFragment { + @SuppressWarnings("deprecation") @Override @NonNull public Dialog onCreateDialog(Bundle savedInstanceState) { // NB: progress dialog is not AppCompat-ready, and will not appear themed // correctly on older devices - ProgressDialog progress = new ProgressDialog(getContext()); + android.app.ProgressDialog progress = new android.app.ProgressDialog(getContext()); progress.setTitle(null); - progress.setProgressStyle(STYLE_SPINNER); + progress.setProgressStyle(android.app.ProgressDialog.STYLE_SPINNER); progress.setMessage(getString(R.string.ui_dialog_access_token_msg)); progress.setIndeterminate(true); progress.setCancelable(false); diff --git a/app/src/main/java/com/zegoggles/smssync/activity/MainActivity.java b/app/src/main/java/com/zegoggles/smssync/activity/MainActivity.java index a952a8cd8..112efca00 100644 --- a/app/src/main/java/com/zegoggles/smssync/activity/MainActivity.java +++ b/app/src/main/java/com/zegoggles/smssync/activity/MainActivity.java @@ -305,12 +305,7 @@ public boolean onPreferenceStartScreen(PreferenceFragmentCompat caller, Preferen } @Subscribe public void themeChangedEvent(ThemeChangedEvent event) { - if (Build.VERSION.SDK_INT >= HONEYCOMB) { - recreate(); - } else { - Toast.makeText(this, R.string.theme_app_relaunch, Toast.LENGTH_SHORT).show(); - finish(); - } + recreate(); } @Override public void onBackStackChanged() { diff --git a/app/src/main/java/com/zegoggles/smssync/activity/PreferenceTitles.java b/app/src/main/java/com/zegoggles/smssync/activity/PreferenceTitles.java index 970441f20..ea99753c6 100644 --- a/app/src/main/java/com/zegoggles/smssync/activity/PreferenceTitles.java +++ b/app/src/main/java/com/zegoggles/smssync/activity/PreferenceTitles.java @@ -35,7 +35,7 @@ class PreferenceTitles { } else if (PREFERENCE_SCREEN.equals(parser.getName()) && parser.getAttributeCount() > 0) { final @StringRes int titleRes = parser.getAttributeResourceValue(NS, "title", 0); final String key = parser.getAttributeValue(NS, "key"); - if (titleRes > 0 && key != null) { + if (titleRes != 0 && key != null) { titleResources.put(key, titleRes); } } diff --git a/app/src/main/java/com/zegoggles/smssync/activity/donation/DonationActivity.java b/app/src/main/java/com/zegoggles/smssync/activity/donation/DonationActivity.java index 6f4f1a8ab..37001e1fa 100644 --- a/app/src/main/java/com/zegoggles/smssync/activity/donation/DonationActivity.java +++ b/app/src/main/java/com/zegoggles/smssync/activity/donation/DonationActivity.java @@ -65,12 +65,25 @@ public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); billingClient = BillingClient.newBuilder(this).setListener(this).build(); billingClient.startConnection(new BillingClientStateListener() { + @Override public void onBillingSetupFinished(@BillingResponse int resultCode) { log("onBillingSetupFinished(" + resultCode + ")" + Thread.currentThread().getName()); + switch (resultCode) { case OK: queryAvailableSkus(); break; + + case BillingResponse.BILLING_UNAVAILABLE: + case BillingResponse.DEVELOPER_ERROR: + case BillingResponse.ERROR: + case BillingResponse.FEATURE_NOT_SUPPORTED: + case BillingResponse.ITEM_ALREADY_OWNED: + case BillingResponse.ITEM_NOT_OWNED: + case BillingResponse.ITEM_UNAVAILABLE: + case BillingResponse.SERVICE_DISCONNECTED: + case BillingResponse.SERVICE_UNAVAILABLE: + case BillingResponse.USER_CANCELED: default: Toast.makeText(DonationActivity.this, R.string.donation_error_iab_unavailable, LENGTH_LONG).show(); Log.w(TAG, "Problem setting up in-app billing: " + resultCode); @@ -130,23 +143,33 @@ public void onSkuDetailsResponse(@BillingResponse int responseCode, List purchases) { log("onPurchasesUpdated(" + responseCode + ", " + purchases + ")"); String message; - if (responseCode == OK) { - message = getString(R.string.ui_donation_success_message); - } else { - switch (responseCode) { - case ITEM_UNAVAILABLE: - message = getString(R.string.donation_error_unavailable); - break; - case ITEM_ALREADY_OWNED: - message = getString(R.string.donation_error_already_owned); - break; - case USER_CANCELED: - message = getString(R.string.donation_error_canceled); - break; - default: - message = getString(R.string.donation_unspecified_error, responseCode); - } - message = getString(R.string.ui_donation_failure_message, message); + switch (responseCode) { + case OK: + message = getString(R.string.ui_donation_success_message); + break; + case ITEM_UNAVAILABLE: + message = getString(R.string.ui_donation_failure_message, + getString(R.string.donation_error_unavailable)); + break; + case ITEM_ALREADY_OWNED: + message = getString(R.string.ui_donation_failure_message, + getString(R.string.donation_error_already_owned)); + break; + case USER_CANCELED: + message = getString(R.string.ui_donation_failure_message, + getString(R.string.donation_error_canceled)); + break; + case BillingResponse.BILLING_UNAVAILABLE: + case BillingResponse.DEVELOPER_ERROR: + case BillingResponse.ERROR: + case BillingResponse.FEATURE_NOT_SUPPORTED: + case BillingResponse.ITEM_NOT_OWNED: + case BillingResponse.SERVICE_DISCONNECTED: + case BillingResponse.SERVICE_UNAVAILABLE: + default: + message = getString(R.string.ui_donation_failure_message, + getString(R.string.donation_unspecified_error, responseCode)); + break; } Toast.makeText(this, message, LENGTH_LONG).show(); finish(); diff --git a/app/src/main/java/com/zegoggles/smssync/mail/Attachment.java b/app/src/main/java/com/zegoggles/smssync/mail/Attachment.java index df28acd32..290e1db46 100644 --- a/app/src/main/java/com/zegoggles/smssync/mail/Attachment.java +++ b/app/src/main/java/com/zegoggles/smssync/mail/Attachment.java @@ -2,6 +2,7 @@ import android.content.ContentResolver; import android.net.Uri; +import android.support.annotation.NonNull; import android.text.TextUtils; import android.util.Log; import com.fsck.k9.mail.Body; @@ -28,7 +29,7 @@ class Attachment { private Attachment() {} - static MimeBodyPart createPartFromUri(ContentResolver resolver, Uri uri, String filename, String contentType) throws MessagingException { + static MimeBodyPart createPartFromUri(@NonNull ContentResolver resolver, @NonNull Uri uri, String filename, String contentType) throws MessagingException { return createPart(new ResolverBody(resolver, uri), filename, contentType); } @@ -67,7 +68,7 @@ private static class ResolverBody extends Base64Body { private ContentResolver resolver; private Uri uri; - ResolverBody(ContentResolver contentResolver, Uri uri) { + ResolverBody(@NonNull ContentResolver contentResolver, @NonNull Uri uri) { resolver = contentResolver; this.uri = uri; } diff --git a/app/src/main/java/com/zegoggles/smssync/mail/MessageConverter.java b/app/src/main/java/com/zegoggles/smssync/mail/MessageConverter.java index 4470e8f54..7fcefa952 100644 --- a/app/src/main/java/com/zegoggles/smssync/mail/MessageConverter.java +++ b/app/src/main/java/com/zegoggles/smssync/mail/MessageConverter.java @@ -77,14 +77,14 @@ public MessageConverter(Context context, ContactGroupIds allowedIds = contactAccessor.getGroupContactIds(context.getContentResolver(), backupContactGroup); if (LOCAL_LOGV) Log.v(TAG, "whitelisted ids for backup: " + allowedIds); - messageGenerator = new MessageGenerator(this.context, + messageGenerator = new MessageGenerator(context, new Address(userEmail), preferences.getEmailAddressStyle(), - new HeaderGenerator(referenceUid, App.getVersionCode(this.context)), - this.personLookup, + new HeaderGenerator(referenceUid, App.getVersionCode(context)), + personLookup, preferences.getMailSubjectPrefix(), allowedIds, - new MmsSupport(this.context.getContentResolver(), this.personLookup), + new MmsSupport(context.getContentResolver(), personLookup), preferences.getCallLogType(), preferences.getDataTypePreferences()); } diff --git a/app/src/main/java/com/zegoggles/smssync/mail/MmsSupport.java b/app/src/main/java/com/zegoggles/smssync/mail/MmsSupport.java index 0deaa526d..8b98c60b1 100644 --- a/app/src/main/java/com/zegoggles/smssync/mail/MmsSupport.java +++ b/app/src/main/java/com/zegoggles/smssync/mail/MmsSupport.java @@ -29,7 +29,7 @@ class MmsSupport { private final PersonLookup personLookup; private final ContentResolver resolver; - MmsSupport(ContentResolver resolver, PersonLookup personLookup) { + MmsSupport(@NonNull ContentResolver resolver, @NonNull PersonLookup personLookup) { this.resolver = resolver; this.personLookup = personLookup; } diff --git a/app/src/main/java/com/zegoggles/smssync/service/BackupTask.java b/app/src/main/java/com/zegoggles/smssync/service/BackupTask.java index 5f5307c19..245096b0a 100644 --- a/app/src/main/java/com/zegoggles/smssync/service/BackupTask.java +++ b/app/src/main/java/com/zegoggles/smssync/service/BackupTask.java @@ -1,5 +1,6 @@ package com.zegoggles.smssync.service; +import android.annotation.SuppressLint; import android.content.Context; import android.os.AsyncTask; import android.support.annotation.NonNull; @@ -47,6 +48,7 @@ import static com.zegoggles.smssync.service.state.SmsSyncState.LOGIN; class BackupTask extends AsyncTask { + @SuppressLint("StaticFieldLeak") private final SmsBackupService service; private final BackupItemsFetcher fetcher; private final MessageConverter converter; diff --git a/app/src/main/java/com/zegoggles/smssync/service/RestoreTask.java b/app/src/main/java/com/zegoggles/smssync/service/RestoreTask.java index 3550403fa..43cec329d 100644 --- a/app/src/main/java/com/zegoggles/smssync/service/RestoreTask.java +++ b/app/src/main/java/com/zegoggles/smssync/service/RestoreTask.java @@ -1,5 +1,6 @@ package com.zegoggles.smssync.service; +import android.annotation.SuppressLint; import android.content.ContentResolver; import android.content.ContentValues; import android.database.Cursor; @@ -50,6 +51,7 @@ class RestoreTask extends AsyncTask { private Set callLogIds = new HashSet(); private Set uids = new HashSet(); + @SuppressLint("StaticFieldLeak") private final SmsRestoreService service; private final ContentResolver resolver; private final MessageConverter converter; diff --git a/app/src/main/java/com/zegoggles/smssync/service/ServiceBase.java b/app/src/main/java/com/zegoggles/smssync/service/ServiceBase.java index fc3b97169..39af15cf7 100644 --- a/app/src/main/java/com/zegoggles/smssync/service/ServiceBase.java +++ b/app/src/main/java/com/zegoggles/smssync/service/ServiceBase.java @@ -110,9 +110,9 @@ protected Preferences getPreferences() { protected synchronized void acquireLocks() { if (wakeLock == null) { PowerManager pMgr = (PowerManager) getSystemService(POWER_SERVICE); - wakeLock = pMgr.newWakeLock(wakeLockType(), TAG); + wakeLock = pMgr.newWakeLock(wakeLockType(), "com.zegoggles.smssync:"+TAG); } - wakeLock.acquire(); + wakeLock.acquire(10*60*1000L /*10 minutes*/); if (isConnectedViaWifi()) { // we have Wifi, lock it @@ -128,10 +128,8 @@ protected int wakeLockType() { return PowerManager.PARTIAL_WAKE_LOCK; } - @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1) private int getWifiLockType() { - return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1 ? - WifiManager.WIFI_MODE_FULL_HIGH_PERF : WifiManager.WIFI_MODE_FULL; + return WifiManager.WIFI_MODE_FULL_HIGH_PERF; } protected synchronized void releaseLocks() { @@ -180,6 +178,7 @@ protected WifiManager getWifiManager() { return (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE); } + @SuppressWarnings("deprecation") @NonNull NotificationCompat.Builder createNotification(int resId) { return new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.ic_notification) @@ -217,6 +216,7 @@ private boolean isConnectedViaWifi_pre_SDK21() { } @TargetApi(Build.VERSION_CODES.LOLLIPOP) + @SuppressWarnings("deprecation") private boolean isConnectedViaWifi_SDK21() { for (Network network : getConnectivityManager().getAllNetworks()) { final NetworkInfo networkInfo = getConnectivityManager().getNetworkInfo(network); diff --git a/app/src/main/java/com/zegoggles/smssync/service/SmsBackupService.java b/app/src/main/java/com/zegoggles/smssync/service/SmsBackupService.java index fe4d88b04..37d23e164 100644 --- a/app/src/main/java/com/zegoggles/smssync/service/SmsBackupService.java +++ b/app/src/main/java/com/zegoggles/smssync/service/SmsBackupService.java @@ -174,6 +174,7 @@ private void checkCredentials() throws RequiresLoginException { } } + @SuppressWarnings("deprecation") private void legacyCheckConnectivity() throws ConnectivityException { NetworkInfo active = getConnectivityManager().getActiveNetworkInfo(); if (active == null || !active.isConnectedOrConnecting()) { @@ -289,6 +290,7 @@ void notifyUser(int notificationId, NotificationCompat.Builder builder) { getNotifier().notify(notificationId, builder.build()); } + @SuppressWarnings("deprecation") private NotificationCompat.Builder notificationBuilder(int icon, String title, String text) { return new NotificationCompat.Builder(this) .setSmallIcon(icon) diff --git a/app/src/main/res/layout/status.xml b/app/src/main/res/layout/status.xml index ea9fc0b7e..bee362fa7 100644 --- a/app/src/main/res/layout/status.xml +++ b/app/src/main/res/layout/status.xml @@ -76,12 +76,14 @@