From 80130654ec6bebe5d6a43a2102ec0eea6ea3743b Mon Sep 17 00:00:00 2001 From: Pfaffenrodt Date: Sat, 29 Oct 2022 12:12:24 +0200 Subject: [PATCH 01/15] Remove unused field properties --- .../protect/card_locker/AboutActivity.java | 35 +++++++------------ 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/protect/card_locker/AboutActivity.java b/app/src/main/java/protect/card_locker/AboutActivity.java index b839171c5..73a96d720 100644 --- a/app/src/main/java/protect/card_locker/AboutActivity.java +++ b/app/src/main/java/protect/card_locker/AboutActivity.java @@ -21,8 +21,6 @@ import java.util.Calendar; import java.util.List; import androidx.appcompat.app.ActionBar; -import androidx.appcompat.widget.Toolbar; -import androidx.constraintlayout.widget.ConstraintLayout; import androidx.core.text.HtmlCompat; import com.google.android.material.dialog.MaterialAlertDialogBuilder; @@ -30,18 +28,16 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder; import protect.card_locker.databinding.AboutActivityBinding; public class AboutActivity extends CatimaAppCompatActivity implements View.OnClickListener { - private AboutActivityBinding binding; + private static final String TAG = "Catima"; - ConstraintLayout version_history, translate, license, repo, privacy, error, credits, rate; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - binding = AboutActivityBinding.inflate(getLayoutInflater()); + AboutActivityBinding binding = AboutActivityBinding.inflate(getLayoutInflater()); setTitle(R.string.about); setContentView(binding.getRoot()); - Toolbar toolbar = binding.toolbar; - setSupportActionBar(toolbar); + setSupportActionBar(binding.toolbar); ActionBar actionBar = getSupportActionBar(); if (actionBar != null) { actionBar.setDisplayHomeAsUpEnabled(true); @@ -106,22 +102,14 @@ public class AboutActivity extends CatimaAppCompatActivity implements View.OnCli setTitle(String.format(getString(R.string.about_title_fmt), appName)); - version_history = binding.versionHistory; - translate = binding.translate; - license = binding.license; - repo = binding.repo; - privacy = binding.privacy; - error = binding.reportError; - credits = binding.credits; - rate = binding.rate; - version_history.setOnClickListener(this); - translate.setOnClickListener(this); - license.setOnClickListener(this); - repo.setOnClickListener(this); - privacy.setOnClickListener(this); - error.setOnClickListener(this); - rate.setOnClickListener(this); + binding.versionHistory.setOnClickListener(this); + binding.translate.setOnClickListener(this); + binding.license.setOnClickListener(this); + binding.repo.setOnClickListener(this); + binding.privacy.setOnClickListener(this); + binding.reportError.setOnClickListener(this); + binding.rate.setOnClickListener(this); StringBuilder contributorInfo = new StringBuilder(); contributorInfo.append(HtmlCompat.fromHtml(String.format(getString(R.string.app_contributors), contributors.toString()), HtmlCompat.FROM_HTML_MODE_COMPACT)); @@ -132,7 +120,8 @@ public class AboutActivity extends CatimaAppCompatActivity implements View.OnCli contributorInfo.append("\n\n"); contributorInfo.append(HtmlCompat.fromHtml(String.format(getString(R.string.app_resources), resources.toString()), HtmlCompat.FROM_HTML_MODE_COMPACT)); - credits.setOnClickListener(view -> new MaterialAlertDialogBuilder(this) + binding.credits + .setOnClickListener(view -> new MaterialAlertDialogBuilder(this) .setTitle(R.string.credits) .setMessage(contributorInfo.toString()) .setPositiveButton(R.string.ok, (dialogInterface, i) -> { From 77ef0a2833dce0c713f51b0881f3651e6a1b0d35 Mon Sep 17 00:00:00 2001 From: Pfaffenrodt Date: Sat, 29 Oct 2022 12:21:56 +0200 Subject: [PATCH 02/15] Extract same logic to enable back button of toolbar ManageGroupActivity setDisplayShowHomeEnabled was redundant --- app/src/main/java/protect/card_locker/AboutActivity.java | 5 +---- .../java/protect/card_locker/BarcodeSelectorActivity.java | 5 +---- .../java/protect/card_locker/CatimaAppCompatActivity.java | 8 ++++++++ .../java/protect/card_locker/ImportExportActivity.java | 5 +---- .../java/protect/card_locker/LoyaltyCardEditActivity.java | 5 +---- .../java/protect/card_locker/LoyaltyCardViewActivity.java | 5 +---- app/src/main/java/protect/card_locker/MainActivity.java | 7 ++----- .../java/protect/card_locker/ManageGroupActivity.java | 7 +------ .../java/protect/card_locker/ManageGroupsActivity.java | 5 +---- app/src/main/java/protect/card_locker/ScanActivity.java | 5 +---- .../protect/card_locker/preferences/SettingsActivity.java | 5 +---- 11 files changed, 19 insertions(+), 43 deletions(-) diff --git a/app/src/main/java/protect/card_locker/AboutActivity.java b/app/src/main/java/protect/card_locker/AboutActivity.java index 73a96d720..04e5b1791 100644 --- a/app/src/main/java/protect/card_locker/AboutActivity.java +++ b/app/src/main/java/protect/card_locker/AboutActivity.java @@ -38,10 +38,7 @@ public class AboutActivity extends CatimaAppCompatActivity implements View.OnCli setTitle(R.string.about); setContentView(binding.getRoot()); setSupportActionBar(binding.toolbar); - ActionBar actionBar = getSupportActionBar(); - if (actionBar != null) { - actionBar.setDisplayHomeAsUpEnabled(true); - } + enableToolbarBackButton(); StringBuilder contributors = new StringBuilder().append("
"); diff --git a/app/src/main/java/protect/card_locker/BarcodeSelectorActivity.java b/app/src/main/java/protect/card_locker/BarcodeSelectorActivity.java index 3397949aa..2745b6a20 100644 --- a/app/src/main/java/protect/card_locker/BarcodeSelectorActivity.java +++ b/app/src/main/java/protect/card_locker/BarcodeSelectorActivity.java @@ -48,10 +48,7 @@ public class BarcodeSelectorActivity extends CatimaAppCompatActivity implements setContentView(binding.getRoot()); Toolbar toolbar = binding.toolbar; setSupportActionBar(toolbar); - ActionBar actionBar = getSupportActionBar(); - if (actionBar != null) { - actionBar.setDisplayHomeAsUpEnabled(true); - } + enableToolbarBackButton(); EditText cardId = binding.cardId; ListView mBarcodeList = binding.barcodes; diff --git a/app/src/main/java/protect/card_locker/CatimaAppCompatActivity.java b/app/src/main/java/protect/card_locker/CatimaAppCompatActivity.java index 37cd5671a..676106125 100644 --- a/app/src/main/java/protect/card_locker/CatimaAppCompatActivity.java +++ b/app/src/main/java/protect/card_locker/CatimaAppCompatActivity.java @@ -7,6 +7,7 @@ import android.os.Bundle; import android.view.View; import androidx.annotation.Nullable; +import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AppCompatActivity; import androidx.core.view.WindowInsetsControllerCompat; @@ -41,4 +42,11 @@ public class CatimaAppCompatActivity extends AppCompatActivity { // XXX android 9 and below has a nasty rendering bug if the theme was patched earlier Utils.postPatchColors(this); } + + protected void enableToolbarBackButton() { + ActionBar actionBar = getSupportActionBar(); + if (actionBar != null) { + actionBar.setDisplayHomeAsUpEnabled(true); + } + } } diff --git a/app/src/main/java/protect/card_locker/ImportExportActivity.java b/app/src/main/java/protect/card_locker/ImportExportActivity.java index 9b1dccb61..1ad0bd352 100644 --- a/app/src/main/java/protect/card_locker/ImportExportActivity.java +++ b/app/src/main/java/protect/card_locker/ImportExportActivity.java @@ -66,10 +66,7 @@ public class ImportExportActivity extends CatimaAppCompatActivity { setContentView(binding.getRoot()); Toolbar toolbar = binding.toolbar; setSupportActionBar(toolbar); - ActionBar actionBar = getSupportActionBar(); - if (actionBar != null) { - actionBar.setDisplayHomeAsUpEnabled(true); - } + enableToolbarBackButton(); // If the application does not have permissions to external // storage, ask for it now diff --git a/app/src/main/java/protect/card_locker/LoyaltyCardEditActivity.java b/app/src/main/java/protect/card_locker/LoyaltyCardEditActivity.java index d909808fd..3dbbf6fd2 100644 --- a/app/src/main/java/protect/card_locker/LoyaltyCardEditActivity.java +++ b/app/src/main/java/protect/card_locker/LoyaltyCardEditActivity.java @@ -307,10 +307,7 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity { setContentView(binding.getRoot()); toolbar = binding.toolbar; setSupportActionBar(toolbar); - ActionBar actionBar = getSupportActionBar(); - if (actionBar != null) { - actionBar.setDisplayHomeAsUpEnabled(true); - } + enableToolbarBackButton(); mDatabase = new DBHelper(this).getWritableDatabase(); diff --git a/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java b/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java index 6019a3953..655cc29e7 100644 --- a/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java +++ b/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java @@ -992,10 +992,7 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements setSupportActionBar(portraitToolbar); } - ActionBar actionBar = getSupportActionBar(); - if (actionBar != null) { - actionBar.setDisplayHomeAsUpEnabled(true); - } + enableToolbarBackButton(); } private void drawBarcode(boolean addPadding) { diff --git a/app/src/main/java/protect/card_locker/MainActivity.java b/app/src/main/java/protect/card_locker/MainActivity.java index 9b2740971..838be16ee 100644 --- a/app/src/main/java/protect/card_locker/MainActivity.java +++ b/app/src/main/java/protect/card_locker/MainActivity.java @@ -249,11 +249,8 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard contentMainBinding = ContentMainBinding.bind(archiveActivityBinding.include.getRoot()); } - if (mArchiveMode) { - ActionBar actionBar = getSupportActionBar(); - if (actionBar != null) { - actionBar.setDisplayHomeAsUpEnabled(true); - } + if(mArchiveMode) { + enableToolbarBackButton(); } mDatabase = new DBHelper(this).getWritableDatabase(); diff --git a/app/src/main/java/protect/card_locker/ManageGroupActivity.java b/app/src/main/java/protect/card_locker/ManageGroupActivity.java index a64c41a8f..a161bf922 100644 --- a/app/src/main/java/protect/card_locker/ManageGroupActivity.java +++ b/app/src/main/java/protect/card_locker/ManageGroupActivity.java @@ -110,12 +110,7 @@ public class ManageGroupActivity extends CatimaAppCompatActivity implements Mana mGroupNameText.setText(inputSavedInstanceState.getString(SAVE_INSTANCE_CURRENT_GROUP_NAME)); } - ActionBar actionBar = getSupportActionBar(); - if (actionBar == null) { - throw (new RuntimeException("mActionBar is not expected to be null here")); - } - actionBar.setDisplayHomeAsUpEnabled(true); - actionBar.setDisplayShowHomeEnabled(true); + enableToolbarBackButton(); saveButton.setOnClickListener(v -> { String currentGroupName = mGroupNameText.getText().toString().trim(); diff --git a/app/src/main/java/protect/card_locker/ManageGroupsActivity.java b/app/src/main/java/protect/card_locker/ManageGroupsActivity.java index 373911de6..592c67006 100644 --- a/app/src/main/java/protect/card_locker/ManageGroupsActivity.java +++ b/app/src/main/java/protect/card_locker/ManageGroupsActivity.java @@ -46,10 +46,7 @@ public class ManageGroupsActivity extends CatimaAppCompatActivity implements Gro setContentView(binding.getRoot()); Toolbar toolbar = binding.toolbar; setSupportActionBar(toolbar); - ActionBar actionBar = getSupportActionBar(); - if (actionBar != null) { - actionBar.setDisplayHomeAsUpEnabled(true); - } + enableToolbarBackButton(); mDatabase = new DBHelper(this).getWritableDatabase(); } diff --git a/app/src/main/java/protect/card_locker/ScanActivity.java b/app/src/main/java/protect/card_locker/ScanActivity.java index 45f953dc2..f23a0b190 100644 --- a/app/src/main/java/protect/card_locker/ScanActivity.java +++ b/app/src/main/java/protect/card_locker/ScanActivity.java @@ -80,10 +80,7 @@ public class ScanActivity extends CatimaAppCompatActivity { setContentView(binding.getRoot()); Toolbar toolbar = binding.toolbar; setSupportActionBar(toolbar); - ActionBar actionBar = getSupportActionBar(); - if (actionBar != null) { - actionBar.setDisplayHomeAsUpEnabled(true); - } + enableToolbarBackButton(); extractIntentFields(getIntent()); diff --git a/app/src/main/java/protect/card_locker/preferences/SettingsActivity.java b/app/src/main/java/protect/card_locker/preferences/SettingsActivity.java index 25e0226fd..5c4f1bb52 100644 --- a/app/src/main/java/protect/card_locker/preferences/SettingsActivity.java +++ b/app/src/main/java/protect/card_locker/preferences/SettingsActivity.java @@ -45,10 +45,7 @@ public class SettingsActivity extends CatimaAppCompatActivity { setContentView(binding.getRoot()); Toolbar toolbar = binding.toolbar; setSupportActionBar(toolbar); - ActionBar actionBar = getSupportActionBar(); - if (actionBar != null) { - actionBar.setDisplayHomeAsUpEnabled(true); - } + enableToolbarBackButton(); // Display the fragment as the main content. fragment = new SettingsFragment(); From 7d284a85bc38b41b159432a27dd6c34d5349367d Mon Sep 17 00:00:00 2001 From: Pfaffenrodt Date: Sat, 29 Oct 2022 12:38:39 +0200 Subject: [PATCH 03/15] Extract about content from onCreate --- .../protect/card_locker/AboutActivity.java | 145 ++++++++++-------- 1 file changed, 83 insertions(+), 62 deletions(-) diff --git a/app/src/main/java/protect/card_locker/AboutActivity.java b/app/src/main/java/protect/card_locker/AboutActivity.java index 04e5b1791..25aab1976 100644 --- a/app/src/main/java/protect/card_locker/AboutActivity.java +++ b/app/src/main/java/protect/card_locker/AboutActivity.java @@ -20,7 +20,6 @@ import java.util.ArrayList; import java.util.Calendar; import java.util.List; -import androidx.appcompat.app.ActionBar; import androidx.core.text.HtmlCompat; import com.google.android.material.dialog.MaterialAlertDialogBuilder; @@ -40,62 +39,12 @@ public class AboutActivity extends CatimaAppCompatActivity implements View.OnCli setSupportActionBar(binding.toolbar); enableToolbarBackButton(); - StringBuilder contributors = new StringBuilder().append("
"); - - BufferedReader reader = new BufferedReader(new InputStreamReader(getResources().openRawResource(R.raw.contributors), StandardCharsets.UTF_8)); - - try { - while (true) { - String tmp = reader.readLine(); - - if (tmp == null || tmp.isEmpty()) { - reader.close(); - break; - } - - contributors.append("
"); - contributors.append(tmp); - } - } catch (IOException ignored) { - } - - final List USED_LIBRARIES = new ArrayList<>(); - USED_LIBRARIES.add(new ThirdPartyInfo("Color Picker", "https://github.com/jaredrummler/ColorPicker", "Apache 2.0")); - USED_LIBRARIES.add(new ThirdPartyInfo("Commons CSV", "https://commons.apache.org/proper/commons-csv/", "Apache 2.0")); - USED_LIBRARIES.add(new ThirdPartyInfo("NumberPickerPreference", "https://github.com/invissvenska/NumberPickerPreference", "GNU LGPL 3.0")); - USED_LIBRARIES.add(new ThirdPartyInfo("uCrop", "https://github.com/Yalantis/uCrop", "Apache 2.0")); - USED_LIBRARIES.add(new ThirdPartyInfo("Zip4j", "https://github.com/srikanth-lingala/zip4j", "Apache 2.0")); - USED_LIBRARIES.add(new ThirdPartyInfo("ZXing", "https://github.com/zxing/zxing", "Apache 2.0")); - USED_LIBRARIES.add(new ThirdPartyInfo("ZXing Android Embedded", "https://github.com/journeyapps/zxing-android-embedded", "Apache 2.0")); - - final List USED_ASSETS = new ArrayList<>(); - USED_ASSETS.add(new ThirdPartyInfo("Android icons", "https://fonts.google.com/icons?selected=Material+Icons", "Apache 2.0")); - - StringBuilder libs = new StringBuilder().append("
"); - for (ThirdPartyInfo entry : USED_LIBRARIES) { - libs.append("
").append(entry.name()).append(" (").append(entry.license()).append(")"); - } - - StringBuilder resources = new StringBuilder().append("
"); - for (ThirdPartyInfo entry : USED_ASSETS) { - resources.append("
").append(entry.name()).append(" (").append(entry.license()).append(")"); - } - String appName = getString(R.string.app_name); - int year = Calendar.getInstance().get(Calendar.YEAR); - - String version = "?"; - try { - PackageInfo pi = getPackageManager().getPackageInfo(getPackageName(), 0); - version = pi.versionName; - } catch (PackageManager.NameNotFoundException e) { - Log.w(TAG, "Package name not found", e); - } TextView copyright = binding.creditsSub; - copyright.setText(String.format(getString(R.string.app_copyright_fmt), year)); + copyright.setText(String.format(getString(R.string.app_copyright_fmt), getCurrentYear())); TextView vHistory = binding.versionHistorySub; - vHistory.setText(String.format(getString(R.string.debug_version_fmt), version)); + vHistory.setText(String.format(getString(R.string.debug_version_fmt), getAppVersion())); setTitle(String.format(getString(R.string.about_title_fmt), appName)); @@ -108,19 +57,11 @@ public class AboutActivity extends CatimaAppCompatActivity implements View.OnCli binding.reportError.setOnClickListener(this); binding.rate.setOnClickListener(this); - StringBuilder contributorInfo = new StringBuilder(); - contributorInfo.append(HtmlCompat.fromHtml(String.format(getString(R.string.app_contributors), contributors.toString()), HtmlCompat.FROM_HTML_MODE_COMPACT)); - contributorInfo.append("\n\n"); - contributorInfo.append(getString(R.string.app_copyright_old)); - contributorInfo.append("\n\n"); - contributorInfo.append(HtmlCompat.fromHtml(String.format(getString(R.string.app_libraries), libs.toString()), HtmlCompat.FROM_HTML_MODE_COMPACT)); - contributorInfo.append("\n\n"); - contributorInfo.append(HtmlCompat.fromHtml(String.format(getString(R.string.app_resources), resources.toString()), HtmlCompat.FROM_HTML_MODE_COMPACT)); binding.credits .setOnClickListener(view -> new MaterialAlertDialogBuilder(this) .setTitle(R.string.credits) - .setMessage(contributorInfo.toString()) + .setMessage(getContributorInfo()) .setPositiveButton(R.string.ok, (dialogInterface, i) -> { }) .show()); @@ -168,4 +109,84 @@ public class AboutActivity extends CatimaAppCompatActivity implements View.OnCli } } + private String getAppVersion() { + String version = "?"; + try { + PackageInfo pi = getPackageManager().getPackageInfo(getPackageName(), 0); + version = pi.versionName; + } catch (PackageManager.NameNotFoundException e) { + Log.w(TAG, "Package name not found", e); + } + + return version; + } + + private int getCurrentYear() { + return Calendar.getInstance().get(Calendar.YEAR); + } + + private String getContributors() { + StringBuilder contributors = new StringBuilder().append("
"); + + BufferedReader reader = new BufferedReader(new InputStreamReader(getResources().openRawResource(R.raw.contributors), StandardCharsets.UTF_8)); + + try { + while (true) { + String tmp = reader.readLine(); + + if (tmp == null || tmp.isEmpty()) { + reader.close(); + break; + } + + contributors.append("
"); + contributors.append(tmp); + } + } catch (IOException ignored) { + } + + return contributors.toString(); + } + + private String getThirdPartyLibraries() { + final List USED_LIBRARIES = new ArrayList<>(); + USED_LIBRARIES.add(new ThirdPartyInfo("Color Picker", "https://github.com/jaredrummler/ColorPicker", "Apache 2.0")); + USED_LIBRARIES.add(new ThirdPartyInfo("Commons CSV", "https://commons.apache.org/proper/commons-csv/", "Apache 2.0")); + USED_LIBRARIES.add(new ThirdPartyInfo("NumberPickerPreference", "https://github.com/invissvenska/NumberPickerPreference", "GNU LGPL 3.0")); + USED_LIBRARIES.add(new ThirdPartyInfo("uCrop", "https://github.com/Yalantis/uCrop", "Apache 2.0")); + USED_LIBRARIES.add(new ThirdPartyInfo("Zip4j", "https://github.com/srikanth-lingala/zip4j", "Apache 2.0")); + USED_LIBRARIES.add(new ThirdPartyInfo("ZXing", "https://github.com/zxing/zxing", "Apache 2.0")); + USED_LIBRARIES.add(new ThirdPartyInfo("ZXing Android Embedded", "https://github.com/journeyapps/zxing-android-embedded", "Apache 2.0")); + StringBuilder libs = new StringBuilder().append("
"); + for (ThirdPartyInfo entry : USED_LIBRARIES) { + libs.append("
").append(entry.name()).append(" (").append(entry.license()).append(")"); + } + + return libs.toString(); + } + + private String getUsedThirdPartyAssets() { + final List USED_ASSETS = new ArrayList<>(); + USED_ASSETS.add(new ThirdPartyInfo("Android icons", "https://fonts.google.com/icons?selected=Material+Icons", "Apache 2.0")); + + StringBuilder resources = new StringBuilder().append("
"); + for (ThirdPartyInfo entry : USED_ASSETS) { + resources.append("
").append(entry.name()).append(" (").append(entry.license()).append(")"); + } + + return resources.toString(); + } + + private String getContributorInfo() { + StringBuilder contributorInfo = new StringBuilder(); + contributorInfo.append(HtmlCompat.fromHtml(String.format(getString(R.string.app_contributors), getContributors()), HtmlCompat.FROM_HTML_MODE_COMPACT)); + contributorInfo.append("\n\n"); + contributorInfo.append(getString(R.string.app_copyright_old)); + contributorInfo.append("\n\n"); + contributorInfo.append(HtmlCompat.fromHtml(String.format(getString(R.string.app_libraries), getThirdPartyLibraries()), HtmlCompat.FROM_HTML_MODE_COMPACT)); + contributorInfo.append("\n\n"); + contributorInfo.append(HtmlCompat.fromHtml(String.format(getString(R.string.app_resources), getUsedThirdPartyAssets()), HtmlCompat.FROM_HTML_MODE_COMPACT)); + + return contributorInfo.toString(); + } } From 08cfb490d41dc21f45a70a8d2e5bdd36da0d19e9 Mon Sep 17 00:00:00 2001 From: Pfaffenrodt Date: Sat, 29 Oct 2022 12:40:14 +0200 Subject: [PATCH 04/15] Remove redundant title setTitle was called twice --- app/src/main/java/protect/card_locker/AboutActivity.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/src/main/java/protect/card_locker/AboutActivity.java b/app/src/main/java/protect/card_locker/AboutActivity.java index 25aab1976..c382a64a9 100644 --- a/app/src/main/java/protect/card_locker/AboutActivity.java +++ b/app/src/main/java/protect/card_locker/AboutActivity.java @@ -34,19 +34,17 @@ public class AboutActivity extends CatimaAppCompatActivity implements View.OnCli protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); AboutActivityBinding binding = AboutActivityBinding.inflate(getLayoutInflater()); - setTitle(R.string.about); + setTitle(String.format(getString(R.string.about_title_fmt), getString(R.string.app_name))); setContentView(binding.getRoot()); setSupportActionBar(binding.toolbar); enableToolbarBackButton(); - String appName = getString(R.string.app_name); TextView copyright = binding.creditsSub; copyright.setText(String.format(getString(R.string.app_copyright_fmt), getCurrentYear())); TextView vHistory = binding.versionHistorySub; vHistory.setText(String.format(getString(R.string.debug_version_fmt), getAppVersion())); - setTitle(String.format(getString(R.string.about_title_fmt), appName)); binding.versionHistory.setOnClickListener(this); From ed7b79ce17c2bde9aef6c37aea892451ab80f723 Mon Sep 17 00:00:00 2001 From: Pfaffenrodt Date: Sat, 29 Oct 2022 12:55:19 +0200 Subject: [PATCH 05/15] Refactor AboutActivity to avoid leaks that hold activity as reference --- .../protect/card_locker/AboutActivity.java | 124 +++++++++++------- 1 file changed, 74 insertions(+), 50 deletions(-) diff --git a/app/src/main/java/protect/card_locker/AboutActivity.java b/app/src/main/java/protect/card_locker/AboutActivity.java index c382a64a9..7f70f6107 100644 --- a/app/src/main/java/protect/card_locker/AboutActivity.java +++ b/app/src/main/java/protect/card_locker/AboutActivity.java @@ -26,14 +26,16 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder; import protect.card_locker.databinding.AboutActivityBinding; -public class AboutActivity extends CatimaAppCompatActivity implements View.OnClickListener { +public class AboutActivity extends CatimaAppCompatActivity { private static final String TAG = "Catima"; + private AboutActivityBinding binding; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - AboutActivityBinding binding = AboutActivityBinding.inflate(getLayoutInflater()); + binding = AboutActivityBinding.inflate(getLayoutInflater()); setTitle(String.format(getString(R.string.about_title_fmt), getString(R.string.app_name))); setContentView(binding.getRoot()); setSupportActionBar(binding.toolbar); @@ -42,27 +44,10 @@ public class AboutActivity extends CatimaAppCompatActivity implements View.OnCli TextView copyright = binding.creditsSub; copyright.setText(String.format(getString(R.string.app_copyright_fmt), getCurrentYear())); - TextView vHistory = binding.versionHistorySub; - vHistory.setText(String.format(getString(R.string.debug_version_fmt), getAppVersion())); + TextView versionHistory = binding.versionHistorySub; + versionHistory.setText(String.format(getString(R.string.debug_version_fmt), getAppVersion())); - - - binding.versionHistory.setOnClickListener(this); - binding.translate.setOnClickListener(this); - binding.license.setOnClickListener(this); - binding.repo.setOnClickListener(this); - binding.privacy.setOnClickListener(this); - binding.reportError.setOnClickListener(this); - binding.rate.setOnClickListener(this); - - - binding.credits - .setOnClickListener(view -> new MaterialAlertDialogBuilder(this) - .setTitle(R.string.credits) - .setMessage(getContributorInfo()) - .setPositiveButton(R.string.ok, (dialogInterface, i) -> { - }) - .show()); + bindClickListeners(); } @Override @@ -75,36 +60,75 @@ public class AboutActivity extends CatimaAppCompatActivity implements View.OnCli } @Override - public void onClick(View view) { - int id = view.getId(); + protected void onDestroy() { + super.onDestroy(); + clearClickListeners(); + binding = null; + } - String url; - if (id == R.id.version_history) { - url = "https://catima.app/changelog/"; - } else if (id == R.id.translate) { - url = "https://hosted.weblate.org/engage/catima/"; - } else if (id == R.id.license) { - url = "https://github.com/CatimaLoyalty/Android/blob/master/LICENSE"; - } else if (id == R.id.repo) { - url = "https://github.com/CatimaLoyalty/Android/"; - } else if (id == R.id.privacy) { - url = "https://catima.app/privacy-policy/"; - } else if (id == R.id.report_error) { - url = "https://github.com/CatimaLoyalty/Android/issues"; - } else if (id == R.id.rate) { - url = "https://play.google.com/store/apps/details?id=me.hackerchick.catima"; - } else { - return; - } + private void bindClickListeners() { + View.OnClickListener openExternalBrowser = createOpenExternalBrowserClickListener(); - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setData(Uri.parse(url)); - try { - startActivity(intent); - } catch (ActivityNotFoundException e) { - Toast.makeText(this, R.string.failedToOpenUrl, Toast.LENGTH_LONG).show(); - Log.e(TAG, "No activity found to handle intent", e); - } + binding.versionHistory.setOnClickListener(openExternalBrowser); + binding.translate.setOnClickListener(openExternalBrowser); + binding.license.setOnClickListener(openExternalBrowser); + binding.repo.setOnClickListener(openExternalBrowser); + binding.privacy.setOnClickListener(openExternalBrowser); + binding.reportError.setOnClickListener(openExternalBrowser); + binding.rate.setOnClickListener(openExternalBrowser); + + binding.credits + .setOnClickListener(view -> new MaterialAlertDialogBuilder(this) + .setTitle(R.string.credits) + .setMessage(getContributorInfo()) + .setPositiveButton(R.string.ok, (dialogInterface, i) -> { + }) + .show()); + } + + private void clearClickListeners() { + binding.versionHistory.setOnClickListener(null); + binding.translate.setOnClickListener(null); + binding.license.setOnClickListener(null); + binding.repo.setOnClickListener(null); + binding.privacy.setOnClickListener(null); + binding.reportError.setOnClickListener(null); + binding.rate.setOnClickListener(null); + binding.credits.setOnClickListener(null); + } + + private View.OnClickListener createOpenExternalBrowserClickListener() { + return (View view) -> { + int id = view.getId(); + + String url; + if (id == R.id.version_history) { + url = "https://catima.app/changelog/"; + } else if (id == R.id.translate) { + url = "https://hosted.weblate.org/engage/catima/"; + } else if (id == R.id.license) { + url = "https://github.com/CatimaLoyalty/Android/blob/master/LICENSE"; + } else if (id == R.id.repo) { + url = "https://github.com/CatimaLoyalty/Android/"; + } else if (id == R.id.privacy) { + url = "https://catima.app/privacy-policy/"; + } else if (id == R.id.report_error) { + url = "https://github.com/CatimaLoyalty/Android/issues"; + } else if (id == R.id.rate) { + url = "https://play.google.com/store/apps/details?id=me.hackerchick.catima"; + } else { + return; + } + + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setData(Uri.parse(url)); + try { + startActivity(intent); + } catch (ActivityNotFoundException e) { + Toast.makeText(this, R.string.failedToOpenUrl, Toast.LENGTH_LONG).show(); + Log.e(TAG, "No activity found to handle intent", e); + } + }; } private String getAppVersion() { From c71019951c893bf2caa0e5a8a3bf4fa1ffe7e9e9 Mon Sep 17 00:00:00 2001 From: Pfaffenrodt Date: Sat, 29 Oct 2022 13:24:23 +0200 Subject: [PATCH 06/15] Extract open link handler --- .../protect/card_locker/AboutActivity.java | 45 +++---------------- .../card_locker/AboutOpenLinkHandler.java | 44 ++++++++++++++++++ 2 files changed, 50 insertions(+), 39 deletions(-) create mode 100644 app/src/main/java/protect/card_locker/AboutOpenLinkHandler.java diff --git a/app/src/main/java/protect/card_locker/AboutActivity.java b/app/src/main/java/protect/card_locker/AboutActivity.java index 7f70f6107..da7002939 100644 --- a/app/src/main/java/protect/card_locker/AboutActivity.java +++ b/app/src/main/java/protect/card_locker/AboutActivity.java @@ -12,6 +12,11 @@ import android.view.View; import android.widget.TextView; import android.widget.Toast; +import androidx.collection.ArrayMap; +import androidx.core.text.HtmlCompat; + +import com.google.android.material.dialog.MaterialAlertDialogBuilder; + import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; @@ -20,10 +25,6 @@ import java.util.ArrayList; import java.util.Calendar; import java.util.List; -import androidx.core.text.HtmlCompat; - -import com.google.android.material.dialog.MaterialAlertDialogBuilder; - import protect.card_locker.databinding.AboutActivityBinding; public class AboutActivity extends CatimaAppCompatActivity { @@ -67,7 +68,7 @@ public class AboutActivity extends CatimaAppCompatActivity { } private void bindClickListeners() { - View.OnClickListener openExternalBrowser = createOpenExternalBrowserClickListener(); + View.OnClickListener openExternalBrowser = view -> (new AboutOpenLinkHandler()).open(this, view); binding.versionHistory.setOnClickListener(openExternalBrowser); binding.translate.setOnClickListener(openExternalBrowser); @@ -97,40 +98,6 @@ public class AboutActivity extends CatimaAppCompatActivity { binding.credits.setOnClickListener(null); } - private View.OnClickListener createOpenExternalBrowserClickListener() { - return (View view) -> { - int id = view.getId(); - - String url; - if (id == R.id.version_history) { - url = "https://catima.app/changelog/"; - } else if (id == R.id.translate) { - url = "https://hosted.weblate.org/engage/catima/"; - } else if (id == R.id.license) { - url = "https://github.com/CatimaLoyalty/Android/blob/master/LICENSE"; - } else if (id == R.id.repo) { - url = "https://github.com/CatimaLoyalty/Android/"; - } else if (id == R.id.privacy) { - url = "https://catima.app/privacy-policy/"; - } else if (id == R.id.report_error) { - url = "https://github.com/CatimaLoyalty/Android/issues"; - } else if (id == R.id.rate) { - url = "https://play.google.com/store/apps/details?id=me.hackerchick.catima"; - } else { - return; - } - - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setData(Uri.parse(url)); - try { - startActivity(intent); - } catch (ActivityNotFoundException e) { - Toast.makeText(this, R.string.failedToOpenUrl, Toast.LENGTH_LONG).show(); - Log.e(TAG, "No activity found to handle intent", e); - } - }; - } - private String getAppVersion() { String version = "?"; try { diff --git a/app/src/main/java/protect/card_locker/AboutOpenLinkHandler.java b/app/src/main/java/protect/card_locker/AboutOpenLinkHandler.java new file mode 100644 index 000000000..659c062a1 --- /dev/null +++ b/app/src/main/java/protect/card_locker/AboutOpenLinkHandler.java @@ -0,0 +1,44 @@ +package protect.card_locker; + +import android.content.ActivityNotFoundException; +import android.content.Intent; +import android.net.Uri; +import android.util.Log; +import android.view.View; +import android.widget.Toast; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.collection.ArrayMap; + +public class AboutOpenLinkHandler { + + private static final String TAG = "Catima"; + + private final ArrayMap viewIdToUrlMap = new ArrayMap(); + + AboutOpenLinkHandler() { + viewIdToUrlMap.put(R.id.version_history, "https://catima.app/changelog/"); + viewIdToUrlMap.put(R.id.translate, "https://hosted.weblate.org/engage/catima/"); + viewIdToUrlMap.put(R.id.license, "https://github.com/CatimaLoyalty/Android/blob/master/LICENSE"); + viewIdToUrlMap.put(R.id.repo, "https://github.com/CatimaLoyalty/Android/"); + viewIdToUrlMap.put(R.id.privacy, "https://catima.app/privacy-policy/"); + viewIdToUrlMap.put(R.id.report_error, "https://github.com/CatimaLoyalty/Android/issues"); + viewIdToUrlMap.put(R.id.rate, "https://play.google.com/store/apps/details?id=me.hackerchick.catima"); + } + + public void open(AppCompatActivity activity, View view) { + String url = viewIdToUrlMap.get(view.getId()); + if (url == null) { + return; + } + + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setData(Uri.parse(url)); + try { + activity.startActivity(intent); + } catch (ActivityNotFoundException e) { + Toast.makeText(activity, R.string.failedToOpenUrl, Toast.LENGTH_LONG).show(); + Log.e(TAG, "No activity found to handle intent", e); + } + } +} From f5a0c8f375a3afca56fa16a09e22299ccc339497 Mon Sep 17 00:00:00 2001 From: Pfaffenrodt Date: Sat, 29 Oct 2022 13:31:57 +0200 Subject: [PATCH 07/15] Extract about content --- .../protect/card_locker/AboutActivity.java | 107 +---------------- .../protect/card_locker/AboutContent.java | 112 ++++++++++++++++++ 2 files changed, 118 insertions(+), 101 deletions(-) create mode 100644 app/src/main/java/protect/card_locker/AboutContent.java diff --git a/app/src/main/java/protect/card_locker/AboutActivity.java b/app/src/main/java/protect/card_locker/AboutActivity.java index da7002939..ca59bd18e 100644 --- a/app/src/main/java/protect/card_locker/AboutActivity.java +++ b/app/src/main/java/protect/card_locker/AboutActivity.java @@ -1,29 +1,12 @@ package protect.card_locker; -import android.content.ActivityNotFoundException; -import android.content.Intent; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.net.Uri; import android.os.Bundle; -import android.util.Log; import android.view.MenuItem; import android.view.View; import android.widget.TextView; -import android.widget.Toast; - -import androidx.collection.ArrayMap; -import androidx.core.text.HtmlCompat; import com.google.android.material.dialog.MaterialAlertDialogBuilder; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.List; import protect.card_locker.databinding.AboutActivityBinding; @@ -32,6 +15,7 @@ public class AboutActivity extends CatimaAppCompatActivity { private static final String TAG = "Catima"; private AboutActivityBinding binding; + private AboutContent content; @Override protected void onCreate(Bundle savedInstanceState) { @@ -42,11 +26,12 @@ public class AboutActivity extends CatimaAppCompatActivity { setSupportActionBar(binding.toolbar); enableToolbarBackButton(); + content = new AboutContent(this); TextView copyright = binding.creditsSub; - copyright.setText(String.format(getString(R.string.app_copyright_fmt), getCurrentYear())); + copyright.setText(String.format(getString(R.string.app_copyright_fmt), content.getCurrentYear())); TextView versionHistory = binding.versionHistorySub; - versionHistory.setText(String.format(getString(R.string.debug_version_fmt), getAppVersion())); + versionHistory.setText(String.format(getString(R.string.debug_version_fmt), content.getAppVersion())); bindClickListeners(); } @@ -63,6 +48,7 @@ public class AboutActivity extends CatimaAppCompatActivity { @Override protected void onDestroy() { super.onDestroy(); + content.destroy(); clearClickListeners(); binding = null; } @@ -81,7 +67,7 @@ public class AboutActivity extends CatimaAppCompatActivity { binding.credits .setOnClickListener(view -> new MaterialAlertDialogBuilder(this) .setTitle(R.string.credits) - .setMessage(getContributorInfo()) + .setMessage(content.getContributorInfo()) .setPositiveButton(R.string.ok, (dialogInterface, i) -> { }) .show()); @@ -97,85 +83,4 @@ public class AboutActivity extends CatimaAppCompatActivity { binding.rate.setOnClickListener(null); binding.credits.setOnClickListener(null); } - - private String getAppVersion() { - String version = "?"; - try { - PackageInfo pi = getPackageManager().getPackageInfo(getPackageName(), 0); - version = pi.versionName; - } catch (PackageManager.NameNotFoundException e) { - Log.w(TAG, "Package name not found", e); - } - - return version; - } - - private int getCurrentYear() { - return Calendar.getInstance().get(Calendar.YEAR); - } - - private String getContributors() { - StringBuilder contributors = new StringBuilder().append("
"); - - BufferedReader reader = new BufferedReader(new InputStreamReader(getResources().openRawResource(R.raw.contributors), StandardCharsets.UTF_8)); - - try { - while (true) { - String tmp = reader.readLine(); - - if (tmp == null || tmp.isEmpty()) { - reader.close(); - break; - } - - contributors.append("
"); - contributors.append(tmp); - } - } catch (IOException ignored) { - } - - return contributors.toString(); - } - - private String getThirdPartyLibraries() { - final List USED_LIBRARIES = new ArrayList<>(); - USED_LIBRARIES.add(new ThirdPartyInfo("Color Picker", "https://github.com/jaredrummler/ColorPicker", "Apache 2.0")); - USED_LIBRARIES.add(new ThirdPartyInfo("Commons CSV", "https://commons.apache.org/proper/commons-csv/", "Apache 2.0")); - USED_LIBRARIES.add(new ThirdPartyInfo("NumberPickerPreference", "https://github.com/invissvenska/NumberPickerPreference", "GNU LGPL 3.0")); - USED_LIBRARIES.add(new ThirdPartyInfo("uCrop", "https://github.com/Yalantis/uCrop", "Apache 2.0")); - USED_LIBRARIES.add(new ThirdPartyInfo("Zip4j", "https://github.com/srikanth-lingala/zip4j", "Apache 2.0")); - USED_LIBRARIES.add(new ThirdPartyInfo("ZXing", "https://github.com/zxing/zxing", "Apache 2.0")); - USED_LIBRARIES.add(new ThirdPartyInfo("ZXing Android Embedded", "https://github.com/journeyapps/zxing-android-embedded", "Apache 2.0")); - StringBuilder libs = new StringBuilder().append("
"); - for (ThirdPartyInfo entry : USED_LIBRARIES) { - libs.append("
").append(entry.name()).append(" (").append(entry.license()).append(")"); - } - - return libs.toString(); - } - - private String getUsedThirdPartyAssets() { - final List USED_ASSETS = new ArrayList<>(); - USED_ASSETS.add(new ThirdPartyInfo("Android icons", "https://fonts.google.com/icons?selected=Material+Icons", "Apache 2.0")); - - StringBuilder resources = new StringBuilder().append("
"); - for (ThirdPartyInfo entry : USED_ASSETS) { - resources.append("
").append(entry.name()).append(" (").append(entry.license()).append(")"); - } - - return resources.toString(); - } - - private String getContributorInfo() { - StringBuilder contributorInfo = new StringBuilder(); - contributorInfo.append(HtmlCompat.fromHtml(String.format(getString(R.string.app_contributors), getContributors()), HtmlCompat.FROM_HTML_MODE_COMPACT)); - contributorInfo.append("\n\n"); - contributorInfo.append(getString(R.string.app_copyright_old)); - contributorInfo.append("\n\n"); - contributorInfo.append(HtmlCompat.fromHtml(String.format(getString(R.string.app_libraries), getThirdPartyLibraries()), HtmlCompat.FROM_HTML_MODE_COMPACT)); - contributorInfo.append("\n\n"); - contributorInfo.append(HtmlCompat.fromHtml(String.format(getString(R.string.app_resources), getUsedThirdPartyAssets()), HtmlCompat.FROM_HTML_MODE_COMPACT)); - - return contributorInfo.toString(); - } } diff --git a/app/src/main/java/protect/card_locker/AboutContent.java b/app/src/main/java/protect/card_locker/AboutContent.java new file mode 100644 index 000000000..926418f8f --- /dev/null +++ b/app/src/main/java/protect/card_locker/AboutContent.java @@ -0,0 +1,112 @@ +package protect.card_locker; + +import android.content.Context; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.util.Log; + +import androidx.core.text.HtmlCompat; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; + +public class AboutContent { + + public static final String TAG = "Catima"; + + public Context context; + + public AboutContent(Context context) { + this.context = context; + } + + public void destroy() { + this.context = null; + } + + public String getAppVersion() { + String version = "?"; + try { + PackageInfo pi = context.getPackageManager().getPackageInfo(context.getPackageName(), 0); + version = pi.versionName; + } catch (PackageManager.NameNotFoundException e) { + Log.w(TAG, "Package name not found", e); + } + + return version; + } + + public int getCurrentYear() { + return Calendar.getInstance().get(Calendar.YEAR); + } + + public String getContributors() { + StringBuilder contributors = new StringBuilder().append("
"); + + BufferedReader reader = new BufferedReader(new InputStreamReader(context.getResources().openRawResource(R.raw.contributors), StandardCharsets.UTF_8)); + + try { + while (true) { + String tmp = reader.readLine(); + + if (tmp == null || tmp.isEmpty()) { + reader.close(); + break; + } + + contributors.append("
"); + contributors.append(tmp); + } + } catch (IOException ignored) { + } + + return contributors.toString(); + } + + public String getThirdPartyLibraries() { + final List USED_LIBRARIES = new ArrayList<>(); + USED_LIBRARIES.add(new ThirdPartyInfo("Color Picker", "https://github.com/jaredrummler/ColorPicker", "Apache 2.0")); + USED_LIBRARIES.add(new ThirdPartyInfo("Commons CSV", "https://commons.apache.org/proper/commons-csv/", "Apache 2.0")); + USED_LIBRARIES.add(new ThirdPartyInfo("NumberPickerPreference", "https://github.com/invissvenska/NumberPickerPreference", "GNU LGPL 3.0")); + USED_LIBRARIES.add(new ThirdPartyInfo("uCrop", "https://github.com/Yalantis/uCrop", "Apache 2.0")); + USED_LIBRARIES.add(new ThirdPartyInfo("Zip4j", "https://github.com/srikanth-lingala/zip4j", "Apache 2.0")); + USED_LIBRARIES.add(new ThirdPartyInfo("ZXing", "https://github.com/zxing/zxing", "Apache 2.0")); + USED_LIBRARIES.add(new ThirdPartyInfo("ZXing Android Embedded", "https://github.com/journeyapps/zxing-android-embedded", "Apache 2.0")); + StringBuilder libs = new StringBuilder().append("
"); + for (ThirdPartyInfo entry : USED_LIBRARIES) { + libs.append("
").append(entry.name()).append(" (").append(entry.license()).append(")"); + } + + return libs.toString(); + } + + public String getUsedThirdPartyAssets() { + final List USED_ASSETS = new ArrayList<>(); + USED_ASSETS.add(new ThirdPartyInfo("Android icons", "https://fonts.google.com/icons?selected=Material+Icons", "Apache 2.0")); + + StringBuilder resources = new StringBuilder().append("
"); + for (ThirdPartyInfo entry : USED_ASSETS) { + resources.append("
").append(entry.name()).append(" (").append(entry.license()).append(")"); + } + + return resources.toString(); + } + + public String getContributorInfo() { + StringBuilder contributorInfo = new StringBuilder(); + contributorInfo.append(HtmlCompat.fromHtml(String.format(context.getString(R.string.app_contributors), getContributors()), HtmlCompat.FROM_HTML_MODE_COMPACT)); + contributorInfo.append("\n\n"); + contributorInfo.append(context.getString(R.string.app_copyright_old)); + contributorInfo.append("\n\n"); + contributorInfo.append(HtmlCompat.fromHtml(String.format(context.getString(R.string.app_libraries), getThirdPartyLibraries()), HtmlCompat.FROM_HTML_MODE_COMPACT)); + contributorInfo.append("\n\n"); + contributorInfo.append(HtmlCompat.fromHtml(String.format(context.getString(R.string.app_resources), getUsedThirdPartyAssets()), HtmlCompat.FROM_HTML_MODE_COMPACT)); + + return contributorInfo.toString(); + } +} From 653606fae3b0076a9ed16f64347daa52cdeb7729 Mon Sep 17 00:00:00 2001 From: Pfaffenrodt Date: Sat, 29 Oct 2022 13:36:22 +0200 Subject: [PATCH 08/15] Extract show credits dialog. remove empty listener --- .../java/protect/card_locker/AboutActivity.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/protect/card_locker/AboutActivity.java b/app/src/main/java/protect/card_locker/AboutActivity.java index ca59bd18e..c63ec5e60 100644 --- a/app/src/main/java/protect/card_locker/AboutActivity.java +++ b/app/src/main/java/protect/card_locker/AboutActivity.java @@ -64,13 +64,7 @@ public class AboutActivity extends CatimaAppCompatActivity { binding.reportError.setOnClickListener(openExternalBrowser); binding.rate.setOnClickListener(openExternalBrowser); - binding.credits - .setOnClickListener(view -> new MaterialAlertDialogBuilder(this) - .setTitle(R.string.credits) - .setMessage(content.getContributorInfo()) - .setPositiveButton(R.string.ok, (dialogInterface, i) -> { - }) - .show()); + binding.credits.setOnClickListener(view -> showCredits()); } private void clearClickListeners() { @@ -83,4 +77,12 @@ public class AboutActivity extends CatimaAppCompatActivity { binding.rate.setOnClickListener(null); binding.credits.setOnClickListener(null); } + + private void showCredits() { + new MaterialAlertDialogBuilder(this) + .setTitle(R.string.credits) + .setMessage(content.getContributorInfo()) + .setPositiveButton(R.string.ok, null) + .show(); + } } From d91c207b60904fd1b3ad9401befa7048dbb30087 Mon Sep 17 00:00:00 2001 From: Pfaffenrodt Date: Sat, 29 Oct 2022 13:40:12 +0200 Subject: [PATCH 09/15] Extract last about content --- app/src/main/java/protect/card_locker/AboutActivity.java | 4 ++-- app/src/main/java/protect/card_locker/AboutContent.java | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/protect/card_locker/AboutActivity.java b/app/src/main/java/protect/card_locker/AboutActivity.java index c63ec5e60..5b3e8b45b 100644 --- a/app/src/main/java/protect/card_locker/AboutActivity.java +++ b/app/src/main/java/protect/card_locker/AboutActivity.java @@ -29,9 +29,9 @@ public class AboutActivity extends CatimaAppCompatActivity { content = new AboutContent(this); TextView copyright = binding.creditsSub; - copyright.setText(String.format(getString(R.string.app_copyright_fmt), content.getCurrentYear())); + copyright.setText(content.getCopyright()); TextView versionHistory = binding.versionHistorySub; - versionHistory.setText(String.format(getString(R.string.debug_version_fmt), content.getAppVersion())); + versionHistory.setText(content.getVersionHistory()); bindClickListeners(); } diff --git a/app/src/main/java/protect/card_locker/AboutContent.java b/app/src/main/java/protect/card_locker/AboutContent.java index 926418f8f..96e2bf71e 100644 --- a/app/src/main/java/protect/card_locker/AboutContent.java +++ b/app/src/main/java/protect/card_locker/AboutContent.java @@ -45,6 +45,10 @@ public class AboutContent { return Calendar.getInstance().get(Calendar.YEAR); } + public String getCopyright() { + return String.format(context.getString(R.string.app_copyright_fmt), getCurrentYear()); + } + public String getContributors() { StringBuilder contributors = new StringBuilder().append("
"); @@ -109,4 +113,8 @@ public class AboutContent { return contributorInfo.toString(); } + + public String getVersionHistory() { + return String.format(context.getString(R.string.debug_version_fmt), getAppVersion()); + } } From 85ddc9689c9ed6c73fc1cca6ac4f9c85fd190e8d Mon Sep 17 00:00:00 2001 From: Pfaffenrodt Date: Sat, 29 Oct 2022 13:54:00 +0200 Subject: [PATCH 10/15] Extract common html link of third party info --- .../protect/card_locker/AboutContent.java | 39 ++++++++++--------- .../protect/card_locker/ThirdPartyInfo.java | 4 ++ 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/protect/card_locker/AboutContent.java b/app/src/main/java/protect/card_locker/AboutContent.java index 96e2bf71e..42c49b14b 100644 --- a/app/src/main/java/protect/card_locker/AboutContent.java +++ b/app/src/main/java/protect/card_locker/AboutContent.java @@ -73,32 +73,35 @@ public class AboutContent { } public String getThirdPartyLibraries() { - final List USED_LIBRARIES = new ArrayList<>(); - USED_LIBRARIES.add(new ThirdPartyInfo("Color Picker", "https://github.com/jaredrummler/ColorPicker", "Apache 2.0")); - USED_LIBRARIES.add(new ThirdPartyInfo("Commons CSV", "https://commons.apache.org/proper/commons-csv/", "Apache 2.0")); - USED_LIBRARIES.add(new ThirdPartyInfo("NumberPickerPreference", "https://github.com/invissvenska/NumberPickerPreference", "GNU LGPL 3.0")); - USED_LIBRARIES.add(new ThirdPartyInfo("uCrop", "https://github.com/Yalantis/uCrop", "Apache 2.0")); - USED_LIBRARIES.add(new ThirdPartyInfo("Zip4j", "https://github.com/srikanth-lingala/zip4j", "Apache 2.0")); - USED_LIBRARIES.add(new ThirdPartyInfo("ZXing", "https://github.com/zxing/zxing", "Apache 2.0")); - USED_LIBRARIES.add(new ThirdPartyInfo("ZXing Android Embedded", "https://github.com/journeyapps/zxing-android-embedded", "Apache 2.0")); - StringBuilder libs = new StringBuilder().append("
"); - for (ThirdPartyInfo entry : USED_LIBRARIES) { - libs.append("
").append(entry.name()).append(" (").append(entry.license()).append(")"); + final List usedLibraries = new ArrayList<>(); + usedLibraries.add(new ThirdPartyInfo("Color Picker", "https://github.com/jaredrummler/ColorPicker", "Apache 2.0")); + usedLibraries.add(new ThirdPartyInfo("Commons CSV", "https://commons.apache.org/proper/commons-csv/", "Apache 2.0")); + usedLibraries.add(new ThirdPartyInfo("NumberPickerPreference", "https://github.com/invissvenska/NumberPickerPreference", "GNU LGPL 3.0")); + usedLibraries.add(new ThirdPartyInfo("uCrop", "https://github.com/Yalantis/uCrop", "Apache 2.0")); + usedLibraries.add(new ThirdPartyInfo("Zip4j", "https://github.com/srikanth-lingala/zip4j", "Apache 2.0")); + usedLibraries.add(new ThirdPartyInfo("ZXing", "https://github.com/zxing/zxing", "Apache 2.0")); + usedLibraries.add(new ThirdPartyInfo("ZXing Android Embedded", "https://github.com/journeyapps/zxing-android-embedded", "Apache 2.0")); + + StringBuilder result = new StringBuilder("
"); + for (ThirdPartyInfo entry : usedLibraries) { + result.append("
") + .append(entry.toHtml()); } - return libs.toString(); + return result.toString(); } public String getUsedThirdPartyAssets() { - final List USED_ASSETS = new ArrayList<>(); - USED_ASSETS.add(new ThirdPartyInfo("Android icons", "https://fonts.google.com/icons?selected=Material+Icons", "Apache 2.0")); + final List usedAssets = new ArrayList<>(); + usedAssets.add(new ThirdPartyInfo("Android icons", "https://fonts.google.com/icons?selected=Material+Icons", "Apache 2.0")); - StringBuilder resources = new StringBuilder().append("
"); - for (ThirdPartyInfo entry : USED_ASSETS) { - resources.append("
").append(entry.name()).append(" (").append(entry.license()).append(")"); + StringBuilder result = new StringBuilder().append("
"); + for (ThirdPartyInfo entry : usedAssets) { + result.append("
") + .append(entry.toHtml()); } - return resources.toString(); + return result.toString(); } public String getContributorInfo() { diff --git a/app/src/main/java/protect/card_locker/ThirdPartyInfo.java b/app/src/main/java/protect/card_locker/ThirdPartyInfo.java index 5ae578694..e32472bab 100644 --- a/app/src/main/java/protect/card_locker/ThirdPartyInfo.java +++ b/app/src/main/java/protect/card_locker/ThirdPartyInfo.java @@ -22,4 +22,8 @@ public class ThirdPartyInfo { public String license() { return mLicense; } + + public String toHtml() { + return String.format("%s (%s)", url(), name(), license()); + } } From dff33d3bab572c2c5122248426c14af6cca3b74a Mon Sep 17 00:00:00 2001 From: Pfaffenrodt Date: Sat, 29 Oct 2022 14:08:04 +0200 Subject: [PATCH 11/15] Simplify reading contributors file --- .../protect/card_locker/AboutContent.java | 26 ++++--------------- .../main/java/protect/card_locker/Utils.java | 12 +++++++++ 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/protect/card_locker/AboutContent.java b/app/src/main/java/protect/card_locker/AboutContent.java index 42c49b14b..45375a482 100644 --- a/app/src/main/java/protect/card_locker/AboutContent.java +++ b/app/src/main/java/protect/card_locker/AboutContent.java @@ -7,10 +7,7 @@ import android.util.Log; import androidx.core.text.HtmlCompat; -import java.io.BufferedReader; import java.io.IOException; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Calendar; import java.util.List; @@ -50,26 +47,13 @@ public class AboutContent { } public String getContributors() { - StringBuilder contributors = new StringBuilder().append("
"); - - BufferedReader reader = new BufferedReader(new InputStreamReader(context.getResources().openRawResource(R.raw.contributors), StandardCharsets.UTF_8)); - + String contributors; try { - while (true) { - String tmp = reader.readLine(); - - if (tmp == null || tmp.isEmpty()) { - reader.close(); - break; - } - - contributors.append("
"); - contributors.append(tmp); - } - } catch (IOException ignored) { + contributors = "
" + Utils.readTextFile(context, R.raw.contributors); + } catch (IOException ignored) { + return ""; } - - return contributors.toString(); + return contributors.replace("\n", "
"); } public String getThirdPartyLibraries() { diff --git a/app/src/main/java/protect/card_locker/Utils.java b/app/src/main/java/protect/card_locker/Utils.java index 9c7a9a770..bc9f41c6a 100644 --- a/app/src/main/java/protect/card_locker/Utils.java +++ b/app/src/main/java/protect/card_locker/Utils.java @@ -20,6 +20,7 @@ import android.util.TypedValue; import android.view.MenuItem; import android.widget.Toast; +import androidx.annotation.RawRes; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatDelegate; import androidx.core.graphics.ColorUtils; @@ -41,6 +42,7 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; import java.math.BigDecimal; import java.text.NumberFormat; import java.text.ParseException; @@ -550,4 +552,14 @@ public class Utils { final int color = (int) (Math.random() * colors.length()); return colors.getColor(color, Color.BLACK); } + + public static String readTextFile(Context context, @RawRes int resourceId) throws IOException { + InputStream input = context.getResources().openRawResource(resourceId); + int size = input.available(); + byte[] buffer = new byte[size]; + input.read(buffer); + input.close(); + + return new String(buffer); + } } From 332e37b2eb941fe884345262d8a213835b5c71fe Mon Sep 17 00:00:00 2001 From: Pfaffenrodt Date: Sat, 29 Oct 2022 14:09:30 +0200 Subject: [PATCH 12/15] Extract page title to about content --- app/src/main/java/protect/card_locker/AboutActivity.java | 4 ++-- app/src/main/java/protect/card_locker/AboutContent.java | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/protect/card_locker/AboutActivity.java b/app/src/main/java/protect/card_locker/AboutActivity.java index 5b3e8b45b..775c10ddf 100644 --- a/app/src/main/java/protect/card_locker/AboutActivity.java +++ b/app/src/main/java/protect/card_locker/AboutActivity.java @@ -21,12 +21,12 @@ public class AboutActivity extends CatimaAppCompatActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = AboutActivityBinding.inflate(getLayoutInflater()); - setTitle(String.format(getString(R.string.about_title_fmt), getString(R.string.app_name))); + content = new AboutContent(this); + setTitle(content.getPageTitle()); setContentView(binding.getRoot()); setSupportActionBar(binding.toolbar); enableToolbarBackButton(); - content = new AboutContent(this); TextView copyright = binding.creditsSub; copyright.setText(content.getCopyright()); diff --git a/app/src/main/java/protect/card_locker/AboutContent.java b/app/src/main/java/protect/card_locker/AboutContent.java index 45375a482..a05ab333c 100644 --- a/app/src/main/java/protect/card_locker/AboutContent.java +++ b/app/src/main/java/protect/card_locker/AboutContent.java @@ -26,6 +26,10 @@ public class AboutContent { this.context = null; } + public String getPageTitle() { + return String.format(context.getString(R.string.about_title_fmt), context.getString(R.string.app_name)); + } + public String getAppVersion() { String version = "?"; try { From 1aafcdc6ae4779d2ad68b834e4c25538368fc8c0 Mon Sep 17 00:00:00 2001 From: Pfaffenrodt Date: Sat, 29 Oct 2022 14:44:02 +0200 Subject: [PATCH 13/15] Revert to reading file. Missing encoding --- .../main/java/protect/card_locker/Utils.java | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/protect/card_locker/Utils.java b/app/src/main/java/protect/card_locker/Utils.java index bc9f41c6a..0b466a0cb 100644 --- a/app/src/main/java/protect/card_locker/Utils.java +++ b/app/src/main/java/protect/card_locker/Utils.java @@ -36,6 +36,7 @@ import com.google.zxing.RGBLuminanceSource; import com.google.zxing.Result; import com.google.zxing.common.HybridBinarizer; +import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; @@ -43,7 +44,10 @@ import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.StringWriter; import java.math.BigDecimal; +import java.nio.charset.StandardCharsets; import java.text.NumberFormat; import java.text.ParseException; import java.util.Calendar; @@ -555,11 +559,20 @@ public class Utils { public static String readTextFile(Context context, @RawRes int resourceId) throws IOException { InputStream input = context.getResources().openRawResource(resourceId); - int size = input.available(); - byte[] buffer = new byte[size]; - input.read(buffer); - input.close(); + BufferedReader reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8)); + StringBuilder result = new StringBuilder(); + while (true) { + String nextLine = reader.readLine(); - return new String(buffer); + if (nextLine == null || nextLine.isEmpty()) { + reader.close(); + break; + } + + result.append("\n"); + result.append(nextLine); + } + + return result.toString(); } } From 6f777068ab1a3245195ce23ec5ce0549aafadb78 Mon Sep 17 00:00:00 2001 From: Pfaffenrodt Date: Sun, 30 Oct 2022 21:04:35 +0100 Subject: [PATCH 14/15] Remove map from id to link. make link handler more solid --- .../protect/card_locker/AboutActivity.java | 17 +++++-- .../card_locker/AboutOpenLinkHandler.java | 44 ------------------- .../card_locker/OpenWebLinkHandler.java | 29 ++++++++++++ 3 files changed, 43 insertions(+), 47 deletions(-) delete mode 100644 app/src/main/java/protect/card_locker/AboutOpenLinkHandler.java create mode 100644 app/src/main/java/protect/card_locker/OpenWebLinkHandler.java diff --git a/app/src/main/java/protect/card_locker/AboutActivity.java b/app/src/main/java/protect/card_locker/AboutActivity.java index 775c10ddf..026f1ba5c 100644 --- a/app/src/main/java/protect/card_locker/AboutActivity.java +++ b/app/src/main/java/protect/card_locker/AboutActivity.java @@ -27,12 +27,19 @@ public class AboutActivity extends CatimaAppCompatActivity { setSupportActionBar(binding.toolbar); enableToolbarBackButton(); - TextView copyright = binding.creditsSub; copyright.setText(content.getCopyright()); TextView versionHistory = binding.versionHistorySub; versionHistory.setText(content.getVersionHistory()); + binding.versionHistory.setTag("https://catima.app/changelog/"); + binding.translate.setTag("https://hosted.weblate.org/engage/catima/"); + binding.license.setTag("https://github.com/CatimaLoyalty/Android/blob/master/LICENSE"); + binding.repo.setTag("https://github.com/CatimaLoyalty/Android/"); + binding.privacy.setTag("https://catima.app/privacy-policy/"); + binding.reportError.setTag("https://github.com/CatimaLoyalty/Android/issues"); + binding.rate.setTag("https://play.google.com/store/apps/details?id=me.hackerchick.catima"); + bindClickListeners(); } @@ -54,8 +61,12 @@ public class AboutActivity extends CatimaAppCompatActivity { } private void bindClickListeners() { - View.OnClickListener openExternalBrowser = view -> (new AboutOpenLinkHandler()).open(this, view); - + View.OnClickListener openExternalBrowser = view -> { + Object tag = view.getTag(); + if (tag instanceof String && ((String) tag).startsWith("https://")) { + (new OpenWebLinkHandler()).open(this, (String) tag); + } + }; binding.versionHistory.setOnClickListener(openExternalBrowser); binding.translate.setOnClickListener(openExternalBrowser); binding.license.setOnClickListener(openExternalBrowser); diff --git a/app/src/main/java/protect/card_locker/AboutOpenLinkHandler.java b/app/src/main/java/protect/card_locker/AboutOpenLinkHandler.java deleted file mode 100644 index 659c062a1..000000000 --- a/app/src/main/java/protect/card_locker/AboutOpenLinkHandler.java +++ /dev/null @@ -1,44 +0,0 @@ -package protect.card_locker; - -import android.content.ActivityNotFoundException; -import android.content.Intent; -import android.net.Uri; -import android.util.Log; -import android.view.View; -import android.widget.Toast; - -import androidx.appcompat.app.AppCompatActivity; -import androidx.collection.ArrayMap; - -public class AboutOpenLinkHandler { - - private static final String TAG = "Catima"; - - private final ArrayMap viewIdToUrlMap = new ArrayMap(); - - AboutOpenLinkHandler() { - viewIdToUrlMap.put(R.id.version_history, "https://catima.app/changelog/"); - viewIdToUrlMap.put(R.id.translate, "https://hosted.weblate.org/engage/catima/"); - viewIdToUrlMap.put(R.id.license, "https://github.com/CatimaLoyalty/Android/blob/master/LICENSE"); - viewIdToUrlMap.put(R.id.repo, "https://github.com/CatimaLoyalty/Android/"); - viewIdToUrlMap.put(R.id.privacy, "https://catima.app/privacy-policy/"); - viewIdToUrlMap.put(R.id.report_error, "https://github.com/CatimaLoyalty/Android/issues"); - viewIdToUrlMap.put(R.id.rate, "https://play.google.com/store/apps/details?id=me.hackerchick.catima"); - } - - public void open(AppCompatActivity activity, View view) { - String url = viewIdToUrlMap.get(view.getId()); - if (url == null) { - return; - } - - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setData(Uri.parse(url)); - try { - activity.startActivity(intent); - } catch (ActivityNotFoundException e) { - Toast.makeText(activity, R.string.failedToOpenUrl, Toast.LENGTH_LONG).show(); - Log.e(TAG, "No activity found to handle intent", e); - } - } -} diff --git a/app/src/main/java/protect/card_locker/OpenWebLinkHandler.java b/app/src/main/java/protect/card_locker/OpenWebLinkHandler.java new file mode 100644 index 000000000..b5c564b61 --- /dev/null +++ b/app/src/main/java/protect/card_locker/OpenWebLinkHandler.java @@ -0,0 +1,29 @@ +package protect.card_locker; + +import android.content.ActivityNotFoundException; +import android.content.Intent; +import android.net.Uri; +import android.util.Log; +import android.widget.Toast; + +import androidx.appcompat.app.AppCompatActivity; + +public class OpenWebLinkHandler { + + private static final String TAG = "Catima"; + + public void open(AppCompatActivity activity, String url) { + if (url == null) { + return; + } + + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setData(Uri.parse(url)); + try { + activity.startActivity(intent); + } catch (ActivityNotFoundException e) { + Toast.makeText(activity, R.string.failedToOpenUrl, Toast.LENGTH_LONG).show(); + Log.e(TAG, "No activity found to handle intent", e); + } + } +} From 8a67d1d02b0370bd3231a9cd043558411e6390bb Mon Sep 17 00:00:00 2001 From: Pfaffenrodt Date: Tue, 1 Nov 2022 10:52:11 +0100 Subject: [PATCH 15/15] Rename open to openBrowser --- app/src/main/java/protect/card_locker/AboutActivity.java | 2 +- app/src/main/java/protect/card_locker/OpenWebLinkHandler.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/protect/card_locker/AboutActivity.java b/app/src/main/java/protect/card_locker/AboutActivity.java index 026f1ba5c..867b4c6bb 100644 --- a/app/src/main/java/protect/card_locker/AboutActivity.java +++ b/app/src/main/java/protect/card_locker/AboutActivity.java @@ -64,7 +64,7 @@ public class AboutActivity extends CatimaAppCompatActivity { View.OnClickListener openExternalBrowser = view -> { Object tag = view.getTag(); if (tag instanceof String && ((String) tag).startsWith("https://")) { - (new OpenWebLinkHandler()).open(this, (String) tag); + (new OpenWebLinkHandler()).openBrowser(this, (String) tag); } }; binding.versionHistory.setOnClickListener(openExternalBrowser); diff --git a/app/src/main/java/protect/card_locker/OpenWebLinkHandler.java b/app/src/main/java/protect/card_locker/OpenWebLinkHandler.java index b5c564b61..1586ac4f2 100644 --- a/app/src/main/java/protect/card_locker/OpenWebLinkHandler.java +++ b/app/src/main/java/protect/card_locker/OpenWebLinkHandler.java @@ -12,7 +12,7 @@ public class OpenWebLinkHandler { private static final String TAG = "Catima"; - public void open(AppCompatActivity activity, String url) { + public void openBrowser(AppCompatActivity activity, String url) { if (url == null) { return; }