diff --git a/app/src/main/java/protect/card_locker/AboutActivity.java b/app/src/main/java/protect/card_locker/AboutActivity.java
index b839171c5..867b4c6bb 100644
--- a/app/src/main/java/protect/card_locker/AboutActivity.java
+++ b/app/src/main/java/protect/card_locker/AboutActivity.java
@@ -1,143 +1,46 @@
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 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 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;
+
import protect.card_locker.databinding.AboutActivityBinding;
-public class AboutActivity extends CatimaAppCompatActivity implements View.OnClickListener {
- private AboutActivityBinding binding;
+public class AboutActivity extends CatimaAppCompatActivity {
+
private static final String TAG = "Catima";
- ConstraintLayout version_history, translate, license, repo, privacy, error, credits, rate;
+
+ private AboutActivityBinding binding;
+ private AboutContent content;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = AboutActivityBinding.inflate(getLayoutInflater());
- setTitle(R.string.about);
+ content = new AboutContent(this);
+ setTitle(content.getPageTitle());
setContentView(binding.getRoot());
- Toolbar toolbar = binding.toolbar;
- setSupportActionBar(toolbar);
- ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- }
-
- 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);
- }
+ setSupportActionBar(binding.toolbar);
+ enableToolbarBackButton();
TextView copyright = binding.creditsSub;
- copyright.setText(String.format(getString(R.string.app_copyright_fmt), year));
- TextView vHistory = binding.versionHistorySub;
- vHistory.setText(String.format(getString(R.string.debug_version_fmt), version));
+ copyright.setText(content.getCopyright());
+ TextView versionHistory = binding.versionHistorySub;
+ versionHistory.setText(content.getVersionHistory());
- setTitle(String.format(getString(R.string.about_title_fmt), appName));
+ 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");
- 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);
-
- 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));
-
- credits.setOnClickListener(view -> new MaterialAlertDialogBuilder(this)
- .setTitle(R.string.credits)
- .setMessage(contributorInfo.toString())
- .setPositiveButton(R.string.ok, (dialogInterface, i) -> {
- })
- .show());
+ bindClickListeners();
}
@Override
@@ -150,36 +53,47 @@ public class AboutActivity extends CatimaAppCompatActivity implements View.OnCli
}
@Override
- public void onClick(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);
- }
+ protected void onDestroy() {
+ super.onDestroy();
+ content.destroy();
+ clearClickListeners();
+ binding = null;
}
+ private void bindClickListeners() {
+ View.OnClickListener openExternalBrowser = view -> {
+ Object tag = view.getTag();
+ if (tag instanceof String && ((String) tag).startsWith("https://")) {
+ (new OpenWebLinkHandler()).openBrowser(this, (String) tag);
+ }
+ };
+ 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 -> showCredits());
+ }
+
+ 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 void showCredits() {
+ new MaterialAlertDialogBuilder(this)
+ .setTitle(R.string.credits)
+ .setMessage(content.getContributorInfo())
+ .setPositiveButton(R.string.ok, null)
+ .show();
+ }
}
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..a05ab333c
--- /dev/null
+++ b/app/src/main/java/protect/card_locker/AboutContent.java
@@ -0,0 +1,111 @@
+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.IOException;
+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 getPageTitle() {
+ return String.format(context.getString(R.string.about_title_fmt), context.getString(R.string.app_name));
+ }
+
+ 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 getCopyright() {
+ return String.format(context.getString(R.string.app_copyright_fmt), getCurrentYear());
+ }
+
+ public String getContributors() {
+ String contributors;
+ try {
+ contributors = "
" + Utils.readTextFile(context, R.raw.contributors);
+ } catch (IOException ignored) {
+ return "";
+ }
+ return contributors.replace("\n", "
");
+ }
+
+ public String getThirdPartyLibraries() {
+ 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 result.toString();
+ }
+
+ public String getUsedThirdPartyAssets() {
+ final List usedAssets = new ArrayList<>();
+ usedAssets.add(new ThirdPartyInfo("Android icons", "https://fonts.google.com/icons?selected=Material+Icons", "Apache 2.0"));
+
+ StringBuilder result = new StringBuilder().append("
");
+ for (ThirdPartyInfo entry : usedAssets) {
+ result.append("
")
+ .append(entry.toHtml());
+ }
+
+ return result.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();
+ }
+
+ public String getVersionHistory() {
+ return String.format(context.getString(R.string.debug_version_fmt), getAppVersion());
+ }
+}
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 96df7bdc2..58f46cc2f 100644
--- a/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java
+++ b/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java
@@ -1005,10 +1005,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/OpenWebLinkHandler.java b/app/src/main/java/protect/card_locker/OpenWebLinkHandler.java
new file mode 100644
index 000000000..1586ac4f2
--- /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 openBrowser(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);
+ }
+ }
+}
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/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());
+ }
}
diff --git a/app/src/main/java/protect/card_locker/Utils.java b/app/src/main/java/protect/card_locker/Utils.java
index 9c7a9a770..0b466a0cb 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;
@@ -35,13 +36,18 @@ 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;
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;
@@ -550,4 +556,23 @@ 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);
+ BufferedReader reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8));
+ StringBuilder result = new StringBuilder();
+ while (true) {
+ String nextLine = reader.readLine();
+
+ if (nextLine == null || nextLine.isEmpty()) {
+ reader.close();
+ break;
+ }
+
+ result.append("\n");
+ result.append(nextLine);
+ }
+
+ return result.toString();
+ }
}
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();