diff --git a/build.gradle b/build.gradle index e1ab1df..a351ddc 100644 --- a/build.gradle +++ b/build.gradle @@ -1,24 +1,24 @@ buildscript { repositories { google() - jcenter() + mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:3.4.0' + classpath 'com.android.tools.build:gradle:7.3.1' } } allprojects { repositories { google() - jcenter() + mavenCentral() } } apply plugin: 'com.android.application' android { - compileSdkVersion 28 + compileSdkVersion 33 compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 @@ -31,10 +31,10 @@ android { } defaultConfig { - minSdkVersion 19 - targetSdkVersion 28 - versionCode 80 - versionName "80" + minSdkVersion 23 + targetSdkVersion 33 + versionCode 81 + versionName "81" } buildTypes { @@ -43,10 +43,11 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } - - lintOptions { + lint { abortOnError false } + namespace 'nitezh.ministock' + } dependencies { diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..33e483c --- /dev/null +++ b/gradle.properties @@ -0,0 +1,3 @@ +android.useAndroidX=true +android.enableJetifier=true +org.gradle.unsafe.configuration-cache=true diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index bfbfdc4..7c66ab6 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Sat May 11 22:19:40 BST 2019 +#Sat Jan 30 12:04:34 GMT 2021 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml index badc818..6046fee 100644 --- a/src/main/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -22,8 +22,7 @@ THE SOFTWARE. --> + xmlns:tools="http://schemas.android.com/tools"> @@ -37,8 +36,8 @@ + android:theme="@android:style/Theme.Dialog" + android:exported="true"> @@ -49,7 +48,8 @@ android:name=".activities.PortfolioActivity" android:configChanges="orientation" android:label="Portfolio" - android:launchMode="singleInstance"> + android:launchMode="singleInstance" + android:exported="true"> @@ -61,7 +61,8 @@ android:configChanges="orientation" android:finishOnTaskLaunch="true" android:label="Preferences" - android:launchMode="singleInstance"> + android:launchMode="singleInstance" + android:exported="false"> @@ -82,7 +83,8 @@ + android:theme="@android:style/Theme.Dialog" + android:exported="false"> @@ -90,7 +92,8 @@ + android:theme="@android:style/Theme.Dialog" + android:exported="false"> @@ -98,7 +101,8 @@ + android:theme="@android:style/Theme.Dialog" + android:exported="false"> @@ -106,7 +110,8 @@ + android:theme="@android:style/Theme.Dialog" + android:exported="false"> @@ -117,7 +122,8 @@ android:configChanges="orientation" android:excludeFromRecents="true" android:launchMode="singleTop" - android:theme="@android:style/Theme.NoTitleBar"> + android:theme="@android:style/Theme.NoTitleBar" + android:exported="false"> @@ -147,7 +153,8 @@ + android:label="Ministocks" + android:exported="true"> @@ -159,7 +166,8 @@ + android:label="Ministocks (wide)" + android:exported="true"> @@ -171,7 +179,8 @@ + android:label="Ministocks (tall)" + android:exported="true"> @@ -183,7 +192,8 @@ + android:label="Ministocks (wide/tall)" + android:exported="true"> diff --git a/src/main/java/nitezh/ministock/BackupAgent.java b/src/main/java/nitezh/ministock/BackupAgent.java index 39fce3a..2079426 100644 --- a/src/main/java/nitezh/ministock/BackupAgent.java +++ b/src/main/java/nitezh/ministock/BackupAgent.java @@ -48,8 +48,7 @@ public void onCreate() { } @Override - public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data, - ParcelFileDescriptor newState) throws IOException { + public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data, ParcelFileDescriptor newState) throws IOException { // Hold the lock while the FileBackupHelper performs backup synchronized (UserData.sFileBackupLock) { super.onBackup(oldState, data, newState); @@ -57,8 +56,7 @@ public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data, } @Override - public void onRestore(BackupDataInput data, int appVersionCode, - ParcelFileDescriptor newState) throws IOException { + public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState) throws IOException { // Hold the lock while the FileBackupHelper restores the file synchronized (UserData.sFileBackupLock) { super.onRestore(data, appVersionCode, newState); diff --git a/src/main/java/nitezh/ministock/CustomAlarmManager.java b/src/main/java/nitezh/ministock/CustomAlarmManager.java index 4ef2c3c..58c9e17 100644 --- a/src/main/java/nitezh/ministock/CustomAlarmManager.java +++ b/src/main/java/nitezh/ministock/CustomAlarmManager.java @@ -46,22 +46,21 @@ public CustomAlarmManager(Context context) { this.appStorage = PreferenceStorage.getInstance(context); this.alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent("UPDATE", null, context, WidgetProvider.class); - this.pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0); + this.pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_IMMUTABLE); } private Long getUpdateInterval() { - return Long.parseLong((this.appStorage.getString("update_interval", - Long.toString(AlarmManager.INTERVAL_HALF_HOUR)))); + return Long.parseLong((this.appStorage.getString("update_interval", Long.toString(AlarmManager.INTERVAL_HALF_HOUR)))); } private int getTimeToNextUpdate(Long updateInterval) { - Double timeToNextUpdate = updateInterval.doubleValue(); - Double elapsedTime = DateTools.elapsedTime(this.appStorage.getString("last_update1", null)); + double timeToNextUpdate = updateInterval.doubleValue(); + double elapsedTime = DateTools.elapsedTime(this.appStorage.getString("last_update1", null)); if (elapsedTime > 0) { timeToNextUpdate = Math.max(updateInterval - elapsedTime, 0); } - return timeToNextUpdate.intValue(); + return (int) timeToNextUpdate; } public void setUpdateTimestamp() { @@ -77,8 +76,7 @@ public void reinitialize() { Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(System.currentTimeMillis()); calendar.add(Calendar.MILLISECOND, this.getTimeToNextUpdate(updateInterval)); - alarmManager.setInexactRepeating(AlarmManager.RTC, calendar.getTimeInMillis(), - updateInterval, pendingIntent); + alarmManager.setInexactRepeating(AlarmManager.RTC, calendar.getTimeInMillis(), updateInterval, pendingIntent); } public void cancel() { diff --git a/src/main/java/nitezh/ministock/DialogTools.java b/src/main/java/nitezh/ministock/DialogTools.java index 0e2ecc5..e92a8ea 100644 --- a/src/main/java/nitezh/ministock/DialogTools.java +++ b/src/main/java/nitezh/ministock/DialogTools.java @@ -45,15 +45,7 @@ public static void showSimpleDialog(Context context, String title, String body) } - public static void alertWithCallback( - Context context, - String title, - String body, - String positiveButtonText, - String negativeButtonText, - final Callable positiveCallback, - final Callable dismissCallback - ) { + public static void alertWithCallback(Context context, String title, String body, String positiveButtonText, String negativeButtonText, final Callable positiveCallback, final Callable dismissCallback) { // Create dialog AlertDialog alertDialog = new AlertDialog.Builder(context).create(); alertDialog.setTitle(title); @@ -72,100 +64,68 @@ public static void alertWithCallback( alertDialog.setView(scroll); // Set the close button text - alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, positiveButtonText, - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - if (positiveCallback != null) { - try { - positiveCallback.call(); - } catch (Exception ignored) { - } - } - } - }); + alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, positiveButtonText, (dialog, which) -> { + if (positiveCallback != null) { + try { + positiveCallback.call(); + } catch (Exception ignored) { + } + } + }); // Optional negative button if (negativeButtonText != null) { - alertDialog.setButton(DialogInterface.BUTTON_NEGATIVE, negativeButtonText, - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - } - }); + alertDialog.setButton(DialogInterface.BUTTON_NEGATIVE, negativeButtonText, (dialog, which) -> { + }); } // Optional dismiss handler - alertDialog.setOnDismissListener(new DialogInterface.OnDismissListener() { - @Override - public void onDismiss(DialogInterface dialog) { - if (dismissCallback != null) { - try { - dismissCallback.call(); - } catch (Exception ignored) { - } + alertDialog.setOnDismissListener(dialog -> { + if (dismissCallback != null) { + try { + dismissCallback.call(); + } catch (Exception ignored) { } } }); alertDialog.show(); } - public static void choiceWithCallback( - Context context, - String title, - String negativeButtonText, - final CharSequence[] choices, - final InputAlertCallable callable - ) { + public static void choiceWithCallback(Context context, String title, String negativeButtonText, final CharSequence[] choices, final InputAlertCallable callable) { // Create dialog AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context); alertDialogBuilder.setTitle(title); // List click handler - alertDialogBuilder.setItems(choices, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - if (callable != null) { - try { - callable.setInputValue(choices[which].toString()); - callable.call(); - } catch (Exception ignored) { - } + alertDialogBuilder.setItems(choices, (dialog, which) -> { + if (callable != null) { + try { + callable.setInputValue(choices[which].toString()); + callable.call(); + } catch (Exception ignored) { } } }); // Optional negative button if (negativeButtonText != null) { - alertDialogBuilder.setNegativeButton(negativeButtonText, - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - } - }); + alertDialogBuilder.setNegativeButton(negativeButtonText, (dialog, which) -> { + }); } // Create alert dialog AlertDialog alertDialog = alertDialogBuilder.create(); - alertDialog.setOnDismissListener(new DialogInterface.OnDismissListener() { - @Override - public void onDismiss(DialogInterface dialog) { - } + alertDialog.setOnDismissListener(dialog -> { }); alertDialog.show(); } - public static void inputWithCallback(Context context, String title, String body, - String positiveButtonText, String negativeButtonText, - String defaultInputText, - final InputAlertCallable callable) { + public static void inputWithCallback(Context context, String title, String body, String positiveButtonText, String negativeButtonText, String defaultInputText, final InputAlertCallable callable) { // Create dialog AlertDialog alertDialog = new AlertDialog.Builder(context).create(); alertDialog.setTitle(title); alertDialog.setMessage(body); // Set an EditText view to get user input - LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT); + LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); layoutParams.setMargins(20, 0, 20, 0); LinearLayout layout = new LinearLayout(context); final EditText input = new EditText(context); @@ -177,27 +137,19 @@ public static void inputWithCallback(Context context, String title, String body, alertDialog.setView(layout); // Set the close button text - alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, positiveButtonText, - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - if (callable != null) { - try { - callable.setInputValue(input.getText().toString()); - callable.call(); - } catch (Exception ignored) { - } - } - } - }); + alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, positiveButtonText, (dialog, which) -> { + if (callable != null) { + try { + callable.setInputValue(input.getText().toString()); + callable.call(); + } catch (Exception ignored) { + } + } + }); // Optional negative button if (negativeButtonText != null) { - alertDialog.setButton(DialogInterface.BUTTON_NEGATIVE, negativeButtonText, - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - } - }); + alertDialog.setButton(DialogInterface.BUTTON_NEGATIVE, negativeButtonText, (dialog, which) -> { + }); } alertDialog.setOnDismissListener(new DialogInterface.OnDismissListener() { @Override diff --git a/src/main/java/nitezh/ministock/PreferenceStorage.java b/src/main/java/nitezh/ministock/PreferenceStorage.java index fe7d537..b78b3a8 100644 --- a/src/main/java/nitezh/ministock/PreferenceStorage.java +++ b/src/main/java/nitezh/ministock/PreferenceStorage.java @@ -29,7 +29,6 @@ of this software and associated documentation files (the "Software"), to deal import android.content.SharedPreferences; import java.util.HashMap; -import java.util.Map; public class PreferenceStorage implements Storage { @@ -41,8 +40,7 @@ public PreferenceStorage(SharedPreferences preferences) { } public static PreferenceStorage getInstance(Context context) { - return new PreferenceStorage(context.getSharedPreferences( - context.getString(R.string.prefs_name), 0)); + return new PreferenceStorage(context.getSharedPreferences(context.getString(R.string.prefs_name), 0)); } @Override @@ -74,10 +72,7 @@ public void apply() { @Override public HashMap getAll() { - HashMap items = new HashMap<>(); - for (Map.Entry entry : this.preferences.getAll().entrySet()) { - items.put(entry.getKey(), entry.getValue()); - } + HashMap items = new HashMap<>(this.preferences.getAll()); return items; } diff --git a/src/main/java/nitezh/ministock/StockSuggestions.java b/src/main/java/nitezh/ministock/StockSuggestions.java index 1e93e0b..557843e 100644 --- a/src/main/java/nitezh/ministock/StockSuggestions.java +++ b/src/main/java/nitezh/ministock/StockSuggestions.java @@ -34,8 +34,6 @@ of this software and associated documentation files (the "Software"), to deal import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import nitezh.ministock.utils.Cache; import nitezh.ministock.utils.StorageCache; @@ -44,8 +42,7 @@ of this software and associated documentation files (the "Software"), to deal class StockSuggestions { - private static final String BASE_URL = "https://s.yimg.com/aq/autoc?callback=YAHOO.Finance.SymbolSuggest.ssCallback®ion=US&lang=en-US&query="; - private static final Pattern PATTERN_RESPONSE = Pattern.compile("YAHOO\\.Finance\\.SymbolSuggest\\.ssCallback\\((\\{.*?\\})\\)"); + private static final String BASE_URL = "https://query2.finance.yahoo.com/v1/finance/search?q="; static List> getSuggestions(String query) { List> suggestions = new ArrayList<>(); @@ -63,26 +60,21 @@ static List> getSuggestions(String query) { if (response == null || response.equals("")) { return suggestions; } - Matcher m = PATTERN_RESPONSE.matcher(response); - if (m.find()) { - response = m.group(1); - try { - JSONArray jsonA = new JSONObject(response) - .getJSONObject("ResultSet") - .getJSONArray("Result"); - - for (int i = 0; i < jsonA.length(); i++) { - Map suggestion = new HashMap<>(); - JSONObject jsonO = jsonA.getJSONObject(i); - suggestion.put("symbol", jsonO.getString("symbol")); - suggestion.put("name", jsonO.getString("name")); - suggestions.add(suggestion); - } - return suggestions; - - } catch (JSONException ignored) { + try { + JSONArray jsonA = new JSONObject(response).getJSONArray("quotes"); + + for (int i = 0; i < jsonA.length(); i++) { + Map suggestion = new HashMap<>(); + JSONObject jsonO = jsonA.getJSONObject(i); + suggestion.put("symbol", jsonO.getString("symbol")); + suggestion.put("name", jsonO.getString("shortname")); + suggestions.add(suggestion); } + return suggestions; + + } catch (JSONException ignored) { } + return suggestions; } } diff --git a/src/main/java/nitezh/ministock/SymbolProvider.java b/src/main/java/nitezh/ministock/SymbolProvider.java index 4c8599d..610059e 100644 --- a/src/main/java/nitezh/ministock/SymbolProvider.java +++ b/src/main/java/nitezh/ministock/SymbolProvider.java @@ -36,6 +36,7 @@ of this software and associated documentation files (the "Software"), to deal import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; /** @@ -53,13 +54,8 @@ public class SymbolProvider extends ContentProvider { * {@link SearchManager} for the details on additional columns that are * supported. */ - private static final String[] COLUMNS = { - "_id", // must include this column - SearchManager.SUGGEST_COLUMN_TEXT_1, - SearchManager.SUGGEST_COLUMN_TEXT_2, - SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA, - SearchManager.SUGGEST_COLUMN_INTENT_DATA - }; + private static final String[] COLUMNS = {"_id", // must include this column + SearchManager.SUGGEST_COLUMN_TEXT_1, SearchManager.SUGGEST_COLUMN_TEXT_2, SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA, SearchManager.SUGGEST_COLUMN_INTENT_DATA}; /** * Sets up a uri matcher for search suggestion and shortcut refresh queries. @@ -106,7 +102,7 @@ private Cursor getSuggestions(String query) { if (!query.equals("")) { boolean symbolFound = false; for (Map suggestion1 : suggestions) { - if (suggestion1.get("symbol").equals(query.toUpperCase())) { + if (Objects.equals(suggestion1.get("symbol"), query.toUpperCase())) { symbolFound = true; break; } diff --git a/src/main/java/nitezh/ministock/UserData.java b/src/main/java/nitezh/ministock/UserData.java index 58b6c5f..34dcb60 100644 --- a/src/main/java/nitezh/ministock/UserData.java +++ b/src/main/java/nitezh/ministock/UserData.java @@ -43,6 +43,7 @@ of this software and associated documentation files (the "Software"), to deal import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; +import java.util.Objects; import java.util.concurrent.Callable; @@ -53,14 +54,14 @@ public class UserData { public static void cleanupPreferenceFiles(Context context) { ArrayList preferencesPathsInUse = getPreferencesPathsInUse(context); - String sharedPrefsPath = context.getFilesDir().getParentFile().getPath() + "/shared_prefs"; + String sharedPrefsPath = Objects.requireNonNull(context.getFilesDir().getParentFile()).getPath() + "/shared_prefs"; removeFilesExceptWhitelist(sharedPrefsPath, preferencesPathsInUse); } private static void removeFilesExceptWhitelist(String sharedPrefsFolder, ArrayList preferencesFilenames) { File sharedPrefsDir = new File(sharedPrefsFolder); if (sharedPrefsDir.exists()) { - for (File f : sharedPrefsDir.listFiles()) { + for (File f : Objects.requireNonNull(sharedPrefsDir.listFiles())) { if (!preferencesFilenames.contains(f.getName())) { //noinspection ResultOfMethodCallIgnored f.delete(); @@ -115,11 +116,9 @@ public static void restoreWidget(Context context, int appWidgetId, String backup JSONObject jsonBackupsForAllWidgets = getJsonBackupsForAllWidgets(context); Widget widget = new AndroidWidgetRepository(context).getWidget(appWidgetId); - widget.setWidgetPreferencesFromJson( - jsonBackupsForAllWidgets.getJSONObject(backupName)); + widget.setWidgetPreferencesFromJson(jsonBackupsForAllWidgets.getJSONObject(backupName)); - Boolean areAllStocksRestored = widget.getSymbolCount() == 10 - && !widget.getStock(4).equals(""); + Boolean areAllStocksRestored = widget.getSymbolCount() == 10 && !widget.getStock(4).equals(""); InformUserWidgetBackupRestoredAndReloadPreferences(context, areAllStocksRestored); } catch (JSONException ignored) { @@ -138,12 +137,9 @@ public static void deleteWidgetBackup(Context context, String backupName) { private static void InformUserWidgetBackupRestoredAndReloadPreferences(Context context, Boolean areAllStocksRestored) { final Context finalContext = context; - Callable callable = new Callable() { - @Override - public Object call() throws Exception { - ReloadPreferences((Activity) finalContext); - return new Object(); - } + Callable callable = () -> { + ReloadPreferences((Activity) finalContext); + return new Object(); }; String msg = "The current widget preferences have been restored from your selected backup."; @@ -151,11 +147,7 @@ public Object call() throws Exception { msg += "

Note: The backup had more stocks than your current widget, so not all stocks were restored."; } - DialogTools.alertWithCallback(context, - "Widget restored", - msg, - "Close", null, - callable, null); + DialogTools.alertWithCallback(context, "Widget restored", msg, "Close", null, callable, null); } private static void ReloadPreferences(Activity activity) { @@ -172,10 +164,10 @@ public static CharSequence[] getWidgetBackupNames(Context context) { } JSONObject jsonBackupsForAllWidgets = getJsonBackupsForAllWidgets(context); - Iterator iterator = jsonBackupsForAllWidgets.keys(); + Iterator iterator = jsonBackupsForAllWidgets.keys(); ArrayList backupList = new ArrayList<>(); while (iterator.hasNext()) { - backupList.add((String) iterator.next()); + backupList.add(iterator.next()); } return backupList.toArray(new String[backupList.size()]); diff --git a/src/main/java/nitezh/ministock/activities/PortfolioActivity.java b/src/main/java/nitezh/ministock/activities/PortfolioActivity.java index 8025f7e..f138ae0 100644 --- a/src/main/java/nitezh/ministock/activities/PortfolioActivity.java +++ b/src/main/java/nitezh/ministock/activities/PortfolioActivity.java @@ -32,10 +32,8 @@ of this software and associated documentation files (the "Software"), to deal import android.view.ContextMenu.ContextMenuInfo; import android.view.MenuItem; import android.view.View; -import android.view.View.OnClickListener; import android.widget.AdapterView; import android.widget.AdapterView.AdapterContextMenuInfo; -import android.widget.AdapterView.OnItemClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.ListView; @@ -46,6 +44,7 @@ of this software and associated documentation files (the "Software"), to deal import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.concurrent.Callable; import nitezh.ministock.DialogTools; @@ -72,10 +71,7 @@ public void onCreate(Bundle savedInstanceState) { Storage storage = PreferenceStorage.getInstance(this); AndroidWidgetRepository widgetRepository = new AndroidWidgetRepository(this); - this.portfolioRepository = new PortfolioStockRepository( - storage, - widgetRepository - ); + this.portfolioRepository = new PortfolioStockRepository(storage, widgetRepository); this.portfolioRepository.updateStocksQuotes(); @@ -86,42 +82,11 @@ private void refreshView() { setContentView(R.layout.portfolio); List> listViewData = this.portfolioRepository.getDisplayInfo(); - SimpleAdapter adapter = new SimpleAdapter(this, listViewData, R.layout.portfolio_list_item, - new String[]{ - "symbol", - "name", - "buyPrice", - "date", - "limitHigh", - "limitLow", - "quantity", - "currentPrice", - "lastChange", - "totalChange", - "holdingValue" - }, - new int[]{ - R.id.portfolio_list_item_symbol, - R.id.portfolio_list_item_name, - R.id.portfolio_list_item_buy_price, - R.id.portfolio_list_item_date, - R.id.portfolio_list_item_limit_high, - R.id.portfolio_list_item_limit_low, - R.id.portfolio_list_item_quantity, - R.id.portfolio_list_item_current_price, - R.id.portfolio_list_item_last_change, - R.id.portfolio_list_item_total_change, - R.id.portfolio_list_item_holding_value - }); - - ListView portfolioListView = (ListView) findViewById(R.id.portfolio_list); + SimpleAdapter adapter = new SimpleAdapter(this, listViewData, R.layout.portfolio_list_item, new String[]{"symbol", "name", "buyPrice", "date", "limitHigh", "limitLow", "quantity", "currentPrice", "lastChange", "totalChange", "holdingValue"}, new int[]{R.id.portfolio_list_item_symbol, R.id.portfolio_list_item_name, R.id.portfolio_list_item_buy_price, R.id.portfolio_list_item_date, R.id.portfolio_list_item_limit_high, R.id.portfolio_list_item_limit_low, R.id.portfolio_list_item_quantity, R.id.portfolio_list_item_current_price, R.id.portfolio_list_item_last_change, R.id.portfolio_list_item_total_change, R.id.portfolio_list_item_holding_value}); + + ListView portfolioListView = findViewById(R.id.portfolio_list); portfolioListView.setAdapter(adapter); - portfolioListView.setOnItemClickListener(new OnItemClickListener() { - @Override - public void onItemClick(AdapterView a, View v, int position, long id) { - showPortfolioItemEdit(a, position); - } - }); + portfolioListView.setOnItemClickListener((a, v, position, id) -> showPortfolioItemEdit(a, position)); registerForContextMenu(portfolioListView); mPortfolioListView = portfolioListView; } @@ -139,17 +104,12 @@ public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuIn @Override public boolean onContextItemSelected(MenuItem item) { if (item.getItemId() == 1) { - Callable callable = new Callable() { - @Override - public Object call() throws Exception { - portfolioRepository.updateStock(mStockSymbol); - refreshView(); - return new Object(); - } + Callable callable = () -> { + portfolioRepository.updateStock(mStockSymbol); + refreshView(); + return new Object(); }; - DialogTools.alertWithCallback(this, "Confirm Delete", - "Clear portfolio info for " + mStockSymbol + "?", "Delete", "Cancel", - callable, null); + DialogTools.alertWithCallback(this, "Confirm Delete", "Clear portfolio info for " + mStockSymbol + "?", "Delete", "Cancel", callable, null); } else if (item.getItemId() == 0) { AdapterContextMenuInfo menuInfo = ((AdapterView.AdapterContextMenuInfo) item.getMenuInfo()); showPortfolioItemEdit(mPortfolioListView, menuInfo.position); @@ -169,8 +129,7 @@ private void showPortfolioItemEdit(AdapterView a, int position) { // Get current data for this stock StockQuote data = this.portfolioRepository.stocksQuotes.get(mStockSymbol); String currentPrice = ""; - if (data != null) - currentPrice = data.getPrice(); + if (data != null) currentPrice = data.getPrice(); // Get portfolio details for this stock String price = stockMap.get("buyPrice") != null ? stockMap.get("buyPrice") : ""; @@ -181,128 +140,121 @@ private void showPortfolioItemEdit(AdapterView a, int position) { String customDisplay = stockMap.get("customName") != null ? stockMap.get("customName") : ""; // If there is no price data, use today's price and date + assert price != null; if (price.equals("")) { price = currentPrice; date = new SimpleDateFormat("yyyy-MM-dd").format(new Date()); } // Initialise the price - EditText priceEditText = (EditText) portfolioItemEdit.findViewById(R.id.portfolio_item_price); + EditText priceEditText = portfolioItemEdit.findViewById(R.id.portfolio_item_price); priceEditText.setText(price); // Initialise the date if the price has been set // to avoid getting the text - EditText dateEditText = (EditText) portfolioItemEdit.findViewById(R.id.portfolio_item_date); - if (!date.equals("") && !price.equals("")) - dateEditText.setText(date); + EditText dateEditText = portfolioItemEdit.findViewById(R.id.portfolio_item_date); + assert date != null; + if (!date.equals("") && !price.equals("")) dateEditText.setText(date); // Initialise the quantity if the price has been set - EditText quantityEditText = (EditText) portfolioItemEdit.findViewById(R.id.portfolio_item_quantity); - if (!quantity.equals("") && !price.equals("")) - quantityEditText.setText(quantity); + EditText quantityEditText = portfolioItemEdit.findViewById(R.id.portfolio_item_quantity); + assert quantity != null; + if (!quantity.equals("") && !price.equals("")) quantityEditText.setText(quantity); // Initialise the limit high if the price has been set - EditText limitHighEditText = (EditText) portfolioItemEdit.findViewById(R.id.portfolio_item_limit_high); - if (!limitHigh.equals("") && !price.equals("")) - limitHighEditText.setText(limitHigh); + EditText limitHighEditText = portfolioItemEdit.findViewById(R.id.portfolio_item_limit_high); + assert limitHigh != null; + if (!limitHigh.equals("") && !price.equals("")) limitHighEditText.setText(limitHigh); // Initialise the limit low if the price has been set - EditText limitLowEditText = (EditText) portfolioItemEdit.findViewById(R.id.portfolio_item_limit_low); - if (!limitLow.equals("") && !price.equals("")) - limitLowEditText.setText(limitLow); + EditText limitLowEditText = portfolioItemEdit.findViewById(R.id.portfolio_item_limit_low); + assert limitLow != null; + if (!limitLow.equals("") && !price.equals("")) limitLowEditText.setText(limitLow); // Initialise the custom display if the price has been set - EditText customDisplayText = (EditText) portfolioItemEdit.findViewById(R.id.portfolio_item_symbol); + EditText customDisplayText = portfolioItemEdit.findViewById(R.id.portfolio_item_symbol); customDisplayText.setInputType(InputType.TYPE_CLASS_TEXT + InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS); + assert customDisplay != null; if (!customDisplay.equals("") && !customDisplay.equals("No description")) customDisplayText.setText(customDisplay); // Setup OK button - Button okButton = (Button) portfolioItemEdit.findViewById(R.id.portfolio_item_save); - okButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - // Retrieve updated price - EditText priceEditText = (EditText) portfolioItemEdit.findViewById(R.id.portfolio_item_price); - String price = priceEditText.getText().toString(); - - // Retrieve updated date - EditText dateEditText = (EditText) portfolioItemEdit.findViewById(R.id.portfolio_item_date); - String date = dateEditText.getText().toString(); - - // Retrieve updated quantity - EditText quantityEditText = (EditText) portfolioItemEdit.findViewById(R.id.portfolio_item_quantity); - String quantity = quantityEditText.getText().toString(); - - // Retrieve updated quantity - EditText limitHighEditText = (EditText) portfolioItemEdit.findViewById(R.id.portfolio_item_limit_high); - String limitHigh = limitHighEditText.getText().toString(); - - // Retrieve updated quantity - EditText limitLowEditText = (EditText) portfolioItemEdit.findViewById(R.id.portfolio_item_limit_low); - String limitLow = limitLowEditText.getText().toString(); - - // Retrieve custom display text - EditText customDisplayText = (EditText) portfolioItemEdit.findViewById(R.id.portfolio_item_symbol); - String customDisplay = customDisplayText.getText().toString(); - - // If the price is empty then clear all other values - if (price.equals("")) { - date = ""; - quantity = ""; - limitHigh = ""; - limitLow = ""; - } - // Otherwise validate the fields - else { - try { - // First validate and parse the data, if this fails then - // dismiss the dialog without making any changes - - price = NumberTools.validatedDoubleString(price); - - // Allow a blank date - if (!date.equals("")) { - SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); - date = formatter.format(formatter.parse(date.replaceAll("[./]", "-"))).toUpperCase(); - } - // Allow a blank quantity - if (!quantity.equals("")) { - quantity = NumberTools.validatedDoubleString(quantity); - } - // Allow a blank limitHigh - if (!limitHigh.equals("")) { - limitHigh = NumberTools.validatedDoubleString(limitHigh); - } - // Allow a blank limitLow - if (!limitLow.equals("")) { - limitLow = NumberTools.validatedDoubleString(limitLow); - } - } catch (Exception e) { - // On error just ignore the input and close the dialog - portfolioItemEdit.dismiss(); - return; + Button okButton = portfolioItemEdit.findViewById(R.id.portfolio_item_save); + okButton.setOnClickListener(v -> { + // Retrieve updated price + EditText priceEditText1 = portfolioItemEdit.findViewById(R.id.portfolio_item_price); + String price1 = priceEditText1.getText().toString(); + + // Retrieve updated date + EditText dateEditText1 = portfolioItemEdit.findViewById(R.id.portfolio_item_date); + String date1 = dateEditText1.getText().toString(); + + // Retrieve updated quantity + EditText quantityEditText1 = portfolioItemEdit.findViewById(R.id.portfolio_item_quantity); + String quantity1 = quantityEditText1.getText().toString(); + + // Retrieve updated quantity + EditText limitHighEditText1 = portfolioItemEdit.findViewById(R.id.portfolio_item_limit_high); + String limitHigh1 = limitHighEditText1.getText().toString(); + + // Retrieve updated quantity + EditText limitLowEditText1 = portfolioItemEdit.findViewById(R.id.portfolio_item_limit_low); + String limitLow1 = limitLowEditText1.getText().toString(); + + // Retrieve custom display text + EditText customDisplayText1 = portfolioItemEdit.findViewById(R.id.portfolio_item_symbol); + String customDisplay1 = customDisplayText1.getText().toString(); + + // If the price is empty then clear all other values + if (price1.equals("")) { + date1 = ""; + quantity1 = ""; + limitHigh1 = ""; + limitLow1 = ""; + } + // Otherwise validate the fields + else { + try { + // First validate and parse the data, if this fails then + // dismiss the dialog without making any changes + + price1 = NumberTools.validatedDoubleString(price1); + + // Allow a blank date + if (!date1.equals("")) { + SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); + date1 = formatter.format(Objects.requireNonNull(formatter.parse(date1.replaceAll("[./]", "-")))).toUpperCase(); } + // Allow a blank quantity + if (!quantity1.equals("")) { + quantity1 = NumberTools.validatedDoubleString(quantity1); + } + // Allow a blank limitHigh + if (!limitHigh1.equals("")) { + limitHigh1 = NumberTools.validatedDoubleString(limitHigh1); + } + // Allow a blank limitLow + if (!limitLow1.equals("")) { + limitLow1 = NumberTools.validatedDoubleString(limitLow1); + } + } catch (Exception e) { + // On error just ignore the input and close the dialog + portfolioItemEdit.dismiss(); + return; } - // If the string only has one digit after the decimal - // point add another one - if (price.indexOf(".") == price.length() - 2) { - price = price + "0"; - } - // Update the actual values - portfolioRepository.updateStock(mStockSymbol, price, date, quantity, - limitHigh, limitLow, customDisplay); - refreshView(); - portfolioItemEdit.dismiss(); } - }); - // Setup Cancel button - Button cancelButton = (Button) portfolioItemEdit.findViewById(R.id.portfolio_item_cancel); - cancelButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - portfolioItemEdit.dismiss(); + // If the string only has one digit after the decimal + // point add another one + if (price1.indexOf(".") == price1.length() - 2) { + price1 = price1 + "0"; } + // Update the actual values + portfolioRepository.updateStock(mStockSymbol, price1, date1, quantity1, limitHigh1, limitLow1, customDisplay1); + refreshView(); + portfolioItemEdit.dismiss(); }); + // Setup Cancel button + Button cancelButton = portfolioItemEdit.findViewById(R.id.portfolio_item_cancel); + cancelButton.setOnClickListener(v -> portfolioItemEdit.dismiss()); // Display the dialog portfolioItemEdit.setTitle(mStockSymbol + " purchase details"); diff --git a/src/main/java/nitezh/ministock/activities/PreferencesActivity.java b/src/main/java/nitezh/ministock/activities/PreferencesActivity.java index 9da142c..d890b67 100644 --- a/src/main/java/nitezh/ministock/activities/PreferencesActivity.java +++ b/src/main/java/nitezh/ministock/activities/PreferencesActivity.java @@ -72,8 +72,7 @@ public class PreferencesActivity extends PreferenceActivity implements OnSharedP // + "New features:

" // + "• Support widget resizing
" // + "• Use updated theme

" - + "Bug fixes:

" - + "• Enable automatic updates on Android 8+"; + + "Bug fixes:

" + "• Enable automatic updates on Android 8+"; // Fields for time pickers private TimePickerDialog.OnTimeSetListener mTimeSetListener; @@ -138,24 +137,20 @@ private void showRecentChanges() { } // Cleanup preferences files UserData.cleanupPreferenceFiles(getApplicationContext()); - @SuppressWarnings("rawtypes") Callable callable = new Callable() { - @Override - public Object call() { - // Ensure we don't show this again - SharedPreferences preferences = getAppPreferences(); - Editor editor = preferences.edit(); - editor.putString("change_log_viewed", VersionTools.BUILD); - - // Set first install if not set - if (preferences.getString("install_date", "").equals("")) { - editor.putString("install_date", new SimpleDateFormat("yyyyMMdd").format(new Date()).toUpperCase()); - } - editor.apply(); - return new Object(); + @SuppressWarnings("rawtypes") Callable callable = () -> { + // Ensure we don't show this again + SharedPreferences preferences = getAppPreferences(); + Editor editor = preferences.edit(); + editor.putString("change_log_viewed", VersionTools.BUILD); + + // Set first install if not set + if (preferences.getString("install_date", "").equals("")) { + editor.putString("install_date", new SimpleDateFormat("yyyyMMdd").format(new Date()).toUpperCase()); } + editor.apply(); + return new Object(); }; - DialogTools.alertWithCallback(this, "BUILD " + VersionTools.BUILD, - getChangeLog(), "Close", null, callable, null); + DialogTools.alertWithCallback(this, "BUILD " + VersionTools.BUILD, getChangeLog(), "Close", null, callable, null); } @Override @@ -184,8 +179,7 @@ protected void onResume() { } // Hide Feedback option if not relevant String install_date = getAppPreferences().getString("install_date", null); - if (DateTools.elapsedDays(install_date) < 30) - removePref("about_menu", "rate_app"); + if (DateTools.elapsedDays(install_date) < 30) removePref("about_menu", "rate_app"); // Initialise the summaries when the preferences screen loads Map map = sharedPreferences.getAll(); @@ -439,32 +433,23 @@ public boolean onPreferenceClick(Preference preference) { }); // Hook the Help preference to the Help activity Preference help_prices = findPreference("help_prices"); - help_prices.setOnPreferenceClickListener(new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - showHelpPrices(); - return true; - } + help_prices.setOnPreferenceClickListener(preference -> { + showHelpPrices(); + return true; }); // Hook the Update preference to the Help activity Preference updateNow = findPreference("update_now"); - updateNow.setOnPreferenceClickListener(new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - mPendingUpdate = true; - finish(); - return true; - } + updateNow.setOnPreferenceClickListener(preference -> { + mPendingUpdate = true; + finish(); + return true; }); // Hook the PortfolioActivity preference to the PortfolioActivity activity Preference portfolio = findPreference("portfolio"); - portfolio.setOnPreferenceClickListener(new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - Intent intent = new Intent(PreferencesActivity.this, PortfolioActivity.class); - startActivity(intent); - return true; - } + portfolio.setOnPreferenceClickListener(preference -> { + Intent intent = new Intent(PreferencesActivity.this, PortfolioActivity.class); + startActivity(intent); + return true; }); /* @@ -508,11 +493,7 @@ public Object call() { return new Object(); } }; - DialogTools.inputWithCallback(PreferencesActivity.this, - "Backup this widget", "Please enter a name for this backup:", - "OK", "Cancel", - "Widget <" + mAppWidgetId + "> from " + DateTools.getNowAsString(), - callable); + DialogTools.inputWithCallback(PreferencesActivity.this, "Backup this widget", "Please enter a name for this backup:", "OK", "Cancel", "Widget <" + mAppWidgetId + "> from " + DateTools.getNowAsString(), callable); return true; } }); @@ -525,8 +506,7 @@ public boolean onPreferenceClick(Preference preference) { CharSequence[] backupNames = UserData.getWidgetBackupNames(PreferencesActivity.this); // If there are no backups show an appropriate dialog if (backupNames == null) { - DialogTools.showSimpleDialog(PreferencesActivity.this, - "No backups available", "There were no widget backups to restore."); + DialogTools.showSimpleDialog(PreferencesActivity.this, "No backups available", "There were no widget backups to restore."); return true; } @@ -538,8 +518,7 @@ public Object call() { return new Object(); } }; - DialogTools.choiceWithCallback(PreferencesActivity.this, - "Select a widget backup to restore", "Cancel", backupNames, callable); + DialogTools.choiceWithCallback(PreferencesActivity.this, "Select a widget backup to restore", "Cancel", backupNames, callable); return true; } }); @@ -552,8 +531,7 @@ public boolean onPreferenceClick(Preference preference) { CharSequence[] backupNames = UserData.getWidgetBackupNames(PreferencesActivity.this); // If there are no backups show an appropriate dialog if (backupNames == null) { - DialogTools.showSimpleDialog(PreferencesActivity.this, - "No backups available to delete", "There were no widget backups to delete."); + DialogTools.showSimpleDialog(PreferencesActivity.this, "No backups available to delete", "There were no widget backups to delete."); return true; } @@ -565,94 +543,72 @@ public Object call() { return new Object(); } }; - DialogTools.choiceWithCallback(PreferencesActivity.this, - "Select a widget backup to delete", "Cancel", backupNames, callable); + DialogTools.choiceWithCallback(PreferencesActivity.this, "Select a widget backup to delete", "Cancel", backupNames, callable); return true; } }); // Hook Rate MinistocksActivity preference to the market link Preference rate_app = findPreference("rate_app"); - rate_app.setOnPreferenceClickListener(new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - showFeedbackOption(); - return true; - } + rate_app.setOnPreferenceClickListener(preference -> { + showFeedbackOption(); + return true; }); // Hook the Online help preference to the online help link Preference online_help = findPreference("online_help"); - online_help.setOnPreferenceClickListener(new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - showOnlineHelp(); - return true; - } + online_help.setOnPreferenceClickListener(preference -> { + showOnlineHelp(); + return true; }); // Hook the Online faqs preference to the online faqs link Preference online_faqs = findPreference("online_faqs"); - online_faqs.setOnPreferenceClickListener(new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - showOnlineFaqs(); - return true; - } + online_faqs.setOnPreferenceClickListener(preference -> { + showOnlineFaqs(); + return true; }); // Hook the Feedback preference to the PortfolioActivity activity Preference feedback = findPreference("feedback"); - feedback.setOnPreferenceClickListener(new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - // Open the e-mail client with destination and subject - Intent intent = new Intent(Intent.ACTION_SEND); - intent.setType("message/rfc822"); - String[] toAddress = {"nitezh@gmail.com"}; - intent.putExtra(Intent.EXTRA_EMAIL, toAddress); - intent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.app_name) + " BUILD " + VersionTools.BUILD); - intent.setType("message/rfc822"); - - // In case we can't launch e-mail, show a dialog - try { - startActivity(intent); - return true; - } catch (Throwable e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - // Show dialog if launching e-mail fails - DialogTools.showSimpleDialog(getApplicationContext(), "Launching e-mail failed", "We were unable to launch your e-mail client automatically.

Our e-mail address for support and feedback is nitezh@gmail.com"); + feedback.setOnPreferenceClickListener(preference -> { + // Open the e-mail client with destination and subject + Intent intent = new Intent(Intent.ACTION_SEND); + intent.setType("message/rfc822"); + String[] toAddress = {"nitezh@gmail.com"}; + intent.putExtra(Intent.EXTRA_EMAIL, toAddress); + intent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.app_name) + " BUILD " + VersionTools.BUILD); + intent.setType("message/rfc822"); + + // In case we can't launch e-mail, show a dialog + try { + startActivity(intent); return true; + } catch (Throwable e) { + // TODO Auto-generated catch block + e.printStackTrace(); } + // Show dialog if launching e-mail fails + DialogTools.showSimpleDialog(getApplicationContext(), "Launching e-mail failed", "We were unable to launch your e-mail client automatically.

Our e-mail address for support and feedback is nitezh@gmail.com"); + return true; }); // Hook the Change history preference to the Change history dialog Preference change_history = findPreference("change_history"); - change_history.setOnPreferenceClickListener(new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - showChangeLog(); - return true; - } + change_history.setOnPreferenceClickListener(preference -> { + showChangeLog(); + return true; }); // Hook the Attributions preference to the Attributions dialog Preference attributions = findPreference("attributions"); - attributions.setOnPreferenceClickListener(new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - showAttributions(); - return true; - } + attributions.setOnPreferenceClickListener(preference -> { + showAttributions(); + return true; }); // Hook the Terms of Service preference to the Terms of Service dialog Preference termsOfService = findPreference("termsOfService"); - termsOfService.setOnPreferenceClickListener(new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - showTermsOfService(); - return true; - } + termsOfService.setOnPreferenceClickListener(preference -> { + showTermsOfService(); + return true; }); // Callback received when the user sets the time in the dialog mTimeSetListener = new TimePickerDialog.OnTimeSetListener() { @@ -663,20 +619,14 @@ public void onTimeSet(TimePicker view, int hourOfDay, int minute) { }; // Hook the Update schedule preferences up Preference update_start = findPreference("update_start"); - update_start.setOnPreferenceClickListener(new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - showTimePickerDialog(preference, "00:00"); - return true; - } + update_start.setOnPreferenceClickListener(preference -> { + showTimePickerDialog(preference, "00:00"); + return true; }); Preference update_end = findPreference("update_end"); - update_end.setOnPreferenceClickListener(new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - showTimePickerDialog(preference, "23:59"); - return true; - } + update_end.setOnPreferenceClickListener(preference -> { + showTimePickerDialog(preference, "23:59"); + return true; }); } @@ -767,11 +717,9 @@ protected void onStop() { // flag is true then do a web update, otherwise do a regular update if (mPendingUpdate) { mPendingUpdate = false; - WidgetProviderBase.updateWidgets(getApplicationContext(), - WidgetProviderBase.UpdateType.VIEW_UPDATE); + WidgetProviderBase.updateWidgets(getApplicationContext(), WidgetProviderBase.UpdateType.VIEW_UPDATE); } else { - WidgetProviderBase.updateWidgetAsync(getApplicationContext(), mAppWidgetId, - WidgetProviderBase.UpdateType.VIEW_NO_UPDATE); + WidgetProviderBase.updateWidgetAsync(getApplicationContext(), mAppWidgetId, WidgetProviderBase.UpdateType.VIEW_NO_UPDATE); } finish(); } @@ -805,15 +753,10 @@ private void showOnlineFaqs() { } private void showFeedbackOption() { - @SuppressWarnings("rawtypes") Callable callable = new Callable() { - @Override - public Object call() { - startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=nitezh.ministock"))); - return new Object(); - } + @SuppressWarnings("rawtypes") Callable callable = () -> { + startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=nitezh.ministock"))); + return new Object(); }; - DialogTools.alertWithCallback(this, "Rate MinistocksActivity", - "Please support MinistocksActivity by giving the application a 5 star rating in the android market.

Motivation to continue to improve the product and add new features comes from positive feedback and ratings.", - "Rate it!", "Close", callable, null); + DialogTools.alertWithCallback(this, "Rate MinistocksActivity", "Please support MinistocksActivity by giving the application a 5 star rating in the android market.

Motivation to continue to improve the product and add new features comes from positive feedback and ratings.", "Rate it!", "Close", callable, null); } } diff --git a/src/main/java/nitezh/ministock/activities/SymbolSearchableActivity.java b/src/main/java/nitezh/ministock/activities/SymbolSearchableActivity.java index e5eb747..5cf6c92 100644 --- a/src/main/java/nitezh/ministock/activities/SymbolSearchableActivity.java +++ b/src/main/java/nitezh/ministock/activities/SymbolSearchableActivity.java @@ -56,7 +56,7 @@ public void onNewIntent(Intent intent) { setResult(RESULT_OK, resultValue); finish(); } else if (Intent.ACTION_SEARCH.equals(intent.getAction())) { - ListAdapter adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, new String[]{String.format("Symbol \'%s\' is not found. Press to add it anyway.", intent.getStringExtra(SearchManager.QUERY))}); + ListAdapter adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, new String[]{String.format("Symbol '%s' is not found. Press to add it anyway.", intent.getStringExtra(SearchManager.QUERY))}); setListAdapter(adapter); } else if (Intent.ACTION_EDIT.equals(intent.getAction())) { startSearch(SearchManager.QUERY, false, null, false); diff --git a/src/main/java/nitezh/ministock/activities/configure/ConfigureActivityBase.java b/src/main/java/nitezh/ministock/activities/configure/ConfigureActivityBase.java index 0cf3076..0b530cb 100644 --- a/src/main/java/nitezh/ministock/activities/configure/ConfigureActivityBase.java +++ b/src/main/java/nitezh/ministock/activities/configure/ConfigureActivityBase.java @@ -43,7 +43,7 @@ abstract class ConfigureActivityBase extends Activity { int mWidgetSize = 0; @Override - public boolean onKeyDown(int keyCode, @SuppressWarnings("NullableProblems") KeyEvent event) { + public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { setupWidget(0); } @@ -75,11 +75,9 @@ public void onCreate(Bundle savedInstanceState) { this.setVisible(false); DialogTools.alertWithCallback(this, "Ministocks Widget Added", "Touch the left side of the widget to view setup options.", "Close", null, null, - new Callable() { - public Object call() throws Exception { - setupWidget(mWidgetSize); - return new Object(); - } + (Callable) () -> { + setupWidget(mWidgetSize); + return new Object(); }); } } diff --git a/src/main/java/nitezh/ministock/activities/widget/WidgetProviderBase.java b/src/main/java/nitezh/ministock/activities/widget/WidgetProviderBase.java index 363b755..5ef2517 100644 --- a/src/main/java/nitezh/ministock/activities/widget/WidgetProviderBase.java +++ b/src/main/java/nitezh/ministock/activities/widget/WidgetProviderBase.java @@ -51,10 +51,8 @@ of this software and associated documentation files (the "Software"), to deal public class WidgetProviderBase extends AppWidgetProvider { - private static void applyUpdate(Context context, int appWidgetId, UpdateType updateMode, - HashMap quotes, String quotesTimeStamp) { - WidgetView widgetView = new WidgetView(context, appWidgetId, updateMode, - quotes, quotesTimeStamp); + private static void applyUpdate(Context context, int appWidgetId, UpdateType updateMode, HashMap quotes, String quotesTimeStamp) { + WidgetView widgetView = new WidgetView(context, appWidgetId, updateMode, quotes, quotesTimeStamp); widgetView.setOnClickPendingIntents(); if (widgetView.hasPendingChanges()) { widgetView.applyPendingChanges(); @@ -63,12 +61,10 @@ private static void applyUpdate(Context context, int appWidgetId, UpdateType upd } public static void updateWidgetAsync(Context context, int appWidgetId, UpdateType updateType) { - try { + new GetDataTask().build(context, appWidgetId, updateType).execute(); - } - // usually occurs when queued tasks = 128 - catch (RejectedExecutionException ignored) { - } + + } public static void updateWidgets(Context context, UpdateType updateType) { @@ -155,9 +151,7 @@ public void onReceive(Context context, Intent intent) { case "RIGHT": Bundle extras = intent.getExtras(); if (extras != null) { - int appWidgetId = extras.getInt( - AppWidgetManager.EXTRA_APPWIDGET_ID, - AppWidgetManager.INVALID_APPWIDGET_ID); + int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); handleTouch(context, appWidgetId, action); } break; @@ -204,22 +198,11 @@ public void onDeleted(Context context, int[] appWidgetIds) { } public enum ViewType { - VIEW_DAILY_PERCENT, - VIEW_DAILY_CHANGE, - VIEW_PORTFOLIO_PERCENT, - VIEW_PORTFOLIO_CHANGE, - VIEW_PORTFOLIO_PERCENT_AER, - VIEW_PL_DAILY_PERCENT, - VIEW_PL_DAILY_CHANGE, - VIEW_PL_PERCENT, - VIEW_PL_CHANGE, - VIEW_PL_PERCENT_AER + VIEW_DAILY_PERCENT, VIEW_DAILY_CHANGE, VIEW_PORTFOLIO_PERCENT, VIEW_PORTFOLIO_CHANGE, VIEW_PORTFOLIO_PERCENT_AER, VIEW_PL_DAILY_PERCENT, VIEW_PL_DAILY_CHANGE, VIEW_PL_PERCENT, VIEW_PL_CHANGE, VIEW_PL_PERCENT_AER } public enum UpdateType { - VIEW_UPDATE, - VIEW_NO_UPDATE, - VIEW_CHANGE + VIEW_UPDATE, VIEW_NO_UPDATE, VIEW_CHANGE } private static class GetDataTask extends AsyncTask { @@ -241,13 +224,9 @@ GetDataTask build(Context context, Integer appWidgetId, UpdateType updateType) { protected Void doInBackground(Object... params) { WidgetRepository widgetRepository = new AndroidWidgetRepository(this.context); Storage storage = PreferenceStorage.getInstance(this.context); - StockQuoteRepository quoteRepository = new StockQuoteRepository( - PreferenceStorage.getInstance(this.context), new StorageCache(storage), - widgetRepository); + StockQuoteRepository quoteRepository = new StockQuoteRepository(PreferenceStorage.getInstance(this.context), new StorageCache(storage), widgetRepository); - this.quotes = quoteRepository.getQuotes( - widgetRepository.getWidget(this.appWidgetId).getSymbols(), - updateType == UpdateType.VIEW_UPDATE); + this.quotes = quoteRepository.getQuotes(widgetRepository.getWidget(this.appWidgetId).getSymbols(), updateType == UpdateType.VIEW_UPDATE); this.timeStamp = quoteRepository.getTimeStamp(); return null; @@ -255,8 +234,7 @@ protected Void doInBackground(Object... params) { @Override protected void onPostExecute(Void result) { - applyUpdate(this.context, this.appWidgetId, this.updateType, this.quotes, - this.timeStamp); + applyUpdate(this.context, this.appWidgetId, this.updateType, this.quotes, this.timeStamp); } } } diff --git a/src/main/java/nitezh/ministock/activities/widget/WidgetView.java b/src/main/java/nitezh/ministock/activities/widget/WidgetView.java index b068474..6f56e34 100644 --- a/src/main/java/nitezh/ministock/activities/widget/WidgetView.java +++ b/src/main/java/nitezh/ministock/activities/widget/WidgetView.java @@ -158,13 +158,13 @@ public void setOnClickPendingIntents() { leftTouchIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, this.widget.getId()); leftTouchIntent.setAction("LEFT"); this.remoteViews.setOnClickPendingIntent(R.id.widget_left, - PendingIntent.getBroadcast(this.context, this.widget.getId(), leftTouchIntent, 0)); + PendingIntent.getBroadcast(this.context, this.widget.getId(), leftTouchIntent, PendingIntent.FLAG_IMMUTABLE)); Intent rightTouchIntent = new Intent(this.context, WidgetProvider.class); rightTouchIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, this.widget.getId()); rightTouchIntent.setAction("RIGHT"); this.remoteViews.setOnClickPendingIntent(R.id.widget_right, - PendingIntent.getBroadcast(this.context, this.widget.getId(), rightTouchIntent, 0)); + PendingIntent.getBroadcast(this.context, this.widget.getId(), rightTouchIntent, PendingIntent.FLAG_IMMUTABLE)); } private HashMap getEnabledViews() { @@ -414,7 +414,7 @@ private int getNextView(UpdateType updateMode) { // Skip views as relevant int count = 0; - while (!this.getEnabledViews().get(ViewType.values()[currentView])) { + while (Boolean.FALSE.equals(this.getEnabledViews().get(ViewType.values()[currentView]))) { count += 1; currentView += 1; currentView = currentView % 10; @@ -641,8 +641,8 @@ private String getTimeStamp() { private boolean canChangeView() { HashMap enabledViews = this.getEnabledViews(); - boolean hasMultipleDefaultViews = enabledViews.get(ViewType.VIEW_DAILY_PERCENT) - && enabledViews.get(ViewType.VIEW_DAILY_CHANGE); + boolean hasMultipleDefaultViews = Boolean.TRUE.equals(enabledViews.get(ViewType.VIEW_DAILY_PERCENT)) + && Boolean.TRUE.equals(enabledViews.get(ViewType.VIEW_DAILY_CHANGE)); return !(this.updateMode == UpdateType.VIEW_CHANGE && !this.hasPortfolioData diff --git a/src/main/java/nitezh/ministock/dataaccess/FxChangeRepository.java b/src/main/java/nitezh/ministock/dataaccess/FxChangeRepository.java index 81f27a1..fca8523 100644 --- a/src/main/java/nitezh/ministock/dataaccess/FxChangeRepository.java +++ b/src/main/java/nitezh/ministock/dataaccess/FxChangeRepository.java @@ -57,8 +57,8 @@ public HashMap getChanges(Cache cache, List symbols) { try { JSONObject jsonChanges = retrieveChangesAsJson(cache); String symbol; - for (Iterator iter = jsonChanges.keys(); iter.hasNext(); ) { - symbol = (String) iter.next(); + for (Iterator iter = jsonChanges.keys(); iter.hasNext(); ) { + symbol = iter.next(); changes.put(symbol, jsonChanges.getString(symbol)); } } catch (JSONException ignored) { diff --git a/src/main/java/nitezh/ministock/dataaccess/GoogleStockQuoteRepository.java b/src/main/java/nitezh/ministock/dataaccess/GoogleStockQuoteRepository.java index fcd55de..852738f 100644 --- a/src/main/java/nitezh/ministock/dataaccess/GoogleStockQuoteRepository.java +++ b/src/main/java/nitezh/ministock/dataaccess/GoogleStockQuoteRepository.java @@ -53,15 +53,7 @@ public HashMap getQuotes(Cache cache, List symbols) for (int i = 0; i < jsonArray.length(); i++) { quoteJson = jsonArray.getJSONObject(i); - StockQuote quote = new StockQuote( - quoteJson.optString("t"), - quoteJson.optString("l_cur", quoteJson.optString("l")).replace(",", ""), - quoteJson.optString("c"), - quoteJson.optString("cp"), - quoteJson.optString("e").replace("INDEX", ""), - "0", - quoteJson.optString("e"), - Locale.US); + StockQuote quote = new StockQuote(quoteJson.optString("t"), quoteJson.optString("l_cur", quoteJson.optString("l")).replace(",", ""), quoteJson.optString("c"), quoteJson.optString("cp"), quoteJson.optString("e").replace("INDEX", ""), "0", quoteJson.optString("e"), Locale.US); quotes.put(quote.getSymbol(), quote); } } catch (JSONException ignored) { diff --git a/src/main/java/nitezh/ministock/dataaccess/IexStockQuoteRepository.java b/src/main/java/nitezh/ministock/dataaccess/IexStockQuoteRepository.java index c7ae9fc..fded7ca 100644 --- a/src/main/java/nitezh/ministock/dataaccess/IexStockQuoteRepository.java +++ b/src/main/java/nitezh/ministock/dataaccess/IexStockQuoteRepository.java @@ -69,16 +69,7 @@ public HashMap getQuotes(Cache cache, List symbols) if (jsonArray != null) { for (int i = 0; i < jsonArray.length(); i++) { quoteJson = jsonArray.getJSONObject(i); - StockQuote quote = new StockQuote( - quoteJson.optString("symbol"), - quoteJson.optString("price"), - quoteJson.optString("change"), - quoteJson.optString("percent"), - quoteJson.optString("exchange"), - quoteJson.optString("volume"), - quoteJson.optString("name"), - fxChanges.get(quoteJson.optString("symbol")), - Locale.US); + StockQuote quote = new StockQuote(quoteJson.optString("symbol"), quoteJson.optString("price"), quoteJson.optString("change"), quoteJson.optString("percent"), quoteJson.optString("exchange"), quoteJson.optString("volume"), quoteJson.optString("name"), fxChanges.get(quoteJson.optString("symbol")), Locale.US); quotes.put(quote.getSymbol(), quote); } } @@ -96,9 +87,7 @@ JSONArray retrieveQuotesAsJson(Cache cache, List symbols) throws JSONExc JSONArray quotes = new JSONArray(); for (String symbol : symbols) { - JSONObject quoteJson = quotesJson - .getJSONObject(symbol) - .getJSONObject("quote"); + JSONObject quoteJson = quotesJson.getJSONObject(symbol).getJSONObject("quote"); JSONObject data = new JSONObject(); data.put("symbol", quoteJson.optString("symbol")); diff --git a/src/main/java/nitezh/ministock/dataaccess/YahooStockQuoteRepository.java b/src/main/java/nitezh/ministock/dataaccess/YahooStockQuoteRepository.java index b25958e..6407336 100644 --- a/src/main/java/nitezh/ministock/dataaccess/YahooStockQuoteRepository.java +++ b/src/main/java/nitezh/ministock/dataaccess/YahooStockQuoteRepository.java @@ -59,16 +59,7 @@ public HashMap getQuotes(Cache cache, List symbols) if (jsonArray != null) { for (int i = 0; i < jsonArray.length(); i++) { quoteJson = jsonArray.getJSONObject(i); - StockQuote quote = new StockQuote( - quoteJson.optString("symbol"), - quoteJson.optString("price"), - quoteJson.optString("change"), - quoteJson.optString("percent"), - quoteJson.optString("exchange"), - quoteJson.optString("volume"), - quoteJson.optString("name"), - fxChanges.get(quoteJson.optString("symbol")), - Locale.US); + StockQuote quote = new StockQuote(quoteJson.optString("symbol"), quoteJson.optString("price"), quoteJson.optString("change"), quoteJson.optString("percent"), quoteJson.optString("exchange"), quoteJson.optString("volume"), quoteJson.optString("name"), fxChanges.get(quoteJson.optString("symbol")), Locale.US); quotes.put(quote.getSymbol(), quote); } } diff --git a/src/main/java/nitezh/ministock/dataaccess/YahooStockQuoteRepository2.java b/src/main/java/nitezh/ministock/dataaccess/YahooStockQuoteRepository2.java index 53df09f..cace4ef 100644 --- a/src/main/java/nitezh/ministock/dataaccess/YahooStockQuoteRepository2.java +++ b/src/main/java/nitezh/ministock/dataaccess/YahooStockQuoteRepository2.java @@ -38,7 +38,7 @@ of this software and associated documentation files (the "Software"), to deal public class YahooStockQuoteRepository2 { -// private static final String BASE_URL = "https://api.iextrading.com/1.0/stock/market/batch"; + // private static final String BASE_URL = "https://api.iextrading.com/1.0/stock/market/batch"; private static final String BASE_URL = "https://query1.finance.yahoo.com/v7/finance/quote?fields=symbol,regularMarketPrice,regularMarketChange,regularMarketChangePercent,regularMarketVolume,shortName,longName"; private final FxChangeRepository fxChangeRepository; @@ -70,16 +70,7 @@ public HashMap getQuotes(Cache cache, List symbols) if (jsonArray != null) { for (int i = 0; i < jsonArray.length(); i++) { quoteJson = jsonArray.getJSONObject(i); - StockQuote quote = new StockQuote( - quoteJson.optString("symbol"), - quoteJson.optString("price"), - quoteJson.optString("change"), - quoteJson.optString("percent"), - quoteJson.optString("exchange"), - quoteJson.optString("volume"), - quoteJson.optString("name"), - fxChanges.get(quoteJson.optString("symbol")), - Locale.US); + StockQuote quote = new StockQuote(quoteJson.optString("symbol"), quoteJson.optString("price"), quoteJson.optString("change"), quoteJson.optString("percent"), quoteJson.optString("exchange"), quoteJson.optString("volume"), quoteJson.optString("name"), fxChanges.get(quoteJson.optString("symbol")), Locale.US); quotes.put(quote.getSymbol(), quote); } } @@ -93,9 +84,7 @@ public HashMap getQuotes(Cache cache, List symbols) JSONArray retrieveQuotesAsJson(Cache cache, List symbols) throws JSONException { String url = buildRequestUrl(symbols); String quotesString = UrlDataTools.getCachedUrlData(url, cache, 300); - JSONArray quotesJson = new JSONObject(quotesString) - .getJSONObject("quoteResponse") - .getJSONArray("result"); + JSONArray quotesJson = new JSONObject(quotesString).getJSONObject("quoteResponse").getJSONArray("result"); JSONObject quoteJson; JSONArray quotes = new JSONArray(); diff --git a/src/main/java/nitezh/ministock/domain/AndroidWidget.java b/src/main/java/nitezh/ministock/domain/AndroidWidget.java index 19ac1a6..f40fe63 100644 --- a/src/main/java/nitezh/ministock/domain/AndroidWidget.java +++ b/src/main/java/nitezh/ministock/domain/AndroidWidget.java @@ -74,8 +74,8 @@ public Storage getStorage() { @Override public void setWidgetPreferencesFromJson(JSONObject jsonPrefs) { String key; - for (Iterator preferenceKey = jsonPrefs.keys(); preferenceKey.hasNext(); ) { - key = (String) preferenceKey.next(); + for (Iterator preferenceKey = jsonPrefs.keys(); preferenceKey.hasNext(); ) { + key = preferenceKey.next(); if (preferencesToNotRestore.contains(key)) { continue; @@ -259,8 +259,7 @@ public boolean hasDailyChangeView() { @Override public boolean hasDailyPercentView() { - return this.storage.getBoolean("show_percent_change", false) - && (size == 0 || size == 2); + return this.storage.getBoolean("show_percent_change", false) && (size == 0 || size == 2); } @Override @@ -270,8 +269,7 @@ public boolean hasTotalChangeView() { @Override public boolean hasTotalPercentView() { - return this.storage.getBoolean("show_portfolio_change", false) - && (size == 0 || size == 2); + return this.storage.getBoolean("show_portfolio_change", false) && (size == 0 || size == 2); } @Override @@ -286,8 +284,7 @@ public boolean hasDailyPlChangeView() { @Override public boolean hasDailyPlPercentView() { - return this.storage.getBoolean("show_profit_daily_change", false) - && (size == 0 || size == 2); + return this.storage.getBoolean("show_profit_daily_change", false) && (size == 0 || size == 2); } @Override @@ -297,8 +294,7 @@ public boolean hasTotalPlChangeView() { @Override public boolean hasTotalPlPercentView() { - return this.storage.getBoolean("show_profit_change", false) - && (size == 0 || size == 2); + return this.storage.getBoolean("show_profit_change", false) && (size == 0 || size == 2); } @Override diff --git a/src/main/java/nitezh/ministock/domain/PortfolioStock.java b/src/main/java/nitezh/ministock/domain/PortfolioStock.java index 8093937..31e083d 100644 --- a/src/main/java/nitezh/ministock/domain/PortfolioStock.java +++ b/src/main/java/nitezh/ministock/domain/PortfolioStock.java @@ -39,15 +39,7 @@ public class PortfolioStock { private final String customName; private final String symbol2; - PortfolioStock( - String price, - String date, - String quantity, - String highLimit, - String lowLimit, - String customName, - String symbol2 - ) { + PortfolioStock(String price, String date, String quantity, String highLimit, String lowLimit, String customName, String symbol2) { this.price = price; this.date = date; this.quantity = quantity; @@ -108,7 +100,6 @@ JSONObject toJson() { } boolean hasData() { - return (this.getPrice() != null && !this.getPrice().equals("") || - (this.getCustomName() != null && !this.getCustomName().equals(""))); + return (this.getPrice() != null && !this.getPrice().equals("") || (this.getCustomName() != null && !this.getCustomName().equals(""))); } } diff --git a/src/main/java/nitezh/ministock/domain/PortfolioStockRepository.java b/src/main/java/nitezh/ministock/domain/PortfolioStockRepository.java index 1b51565..46debd4 100644 --- a/src/main/java/nitezh/ministock/domain/PortfolioStockRepository.java +++ b/src/main/java/nitezh/ministock/domain/PortfolioStockRepository.java @@ -47,8 +47,8 @@ public class PortfolioStockRepository { public static final String WIDGET_JSON = "widgetJson"; public HashMap stocksQuotes = new HashMap<>(); - HashMap portfolioStocksInfo = new HashMap<>(); - private Set widgetsStockSymbols = new HashSet<>(); + HashMap portfolioStocksInfo; + private final Set widgetsStockSymbols; private static final HashMap mPortfolioStocks = new HashMap<>(); private static boolean mDirtyPortfolioStockMap = true; @@ -84,7 +84,7 @@ private HashMap getStocksQuotes() { Set symbolSet = portfolioStocksInfo.keySet(); return stockQuoteRepository - .getQuotes(Arrays.asList(symbolSet.toArray(new String[symbolSet.size()])), false); + .getQuotes(Arrays.asList(symbolSet.toArray(new String[0])), false); } private HashMap getPortfolioStocksInfo(Set symbols) { @@ -152,7 +152,7 @@ private void populateDisplayHoldingValue(NumberFormat numberFormat, String symbo String holdingValue = ""; try { Double holdingQuanta = NumberTools.parseDouble(stock.getQuantity()); - Double holdingPrice = numberFormat.parse(currentPrice).doubleValue(); + Double holdingPrice = Objects.requireNonNull(numberFormat.parse(currentPrice)).doubleValue(); holdingValue = CurrencyTools.addCurrencyToSymbol(String.format(Locale.getDefault(), "%.0f", (holdingQuanta * holdingPrice)), symbol); } catch (Exception ignored) { } @@ -165,8 +165,8 @@ private void populateDisplayLastChange(NumberFormat numberFormat, String symbol, if (quote != null) { lastChange = quote.getPercent(); try { - Double change = numberFormat.parse(quote.getChange()).doubleValue(); - Double totalChange = NumberTools.parseDouble(stock.getQuantity()) * change; + Double change = Objects.requireNonNull(numberFormat.parse(quote.getChange())).doubleValue(); + double totalChange = NumberTools.parseDouble(stock.getQuantity()) * change; lastChange += " / " + CurrencyTools.addCurrencyToSymbol(String.format(Locale.getDefault(), "%.0f", (totalChange)), symbol); } catch (Exception ignored) { } @@ -180,9 +180,9 @@ private void populateDisplayTotalChange(NumberFormat numberFormat, String symbol // Calculate total change, including percentage String totalChange = ""; try { - Double price = numberFormat.parse(currentPrice).doubleValue(); + Double price = Objects.requireNonNull(numberFormat.parse(currentPrice)).doubleValue(); Double buy = NumberTools.parseDouble(buyPrice); - Double totalPercentChange = price - buy; + double totalPercentChange = price - buy; totalChange = String.format(Locale.getDefault(), "%.0f", 100 * totalPercentChange / buy) + "%"; // Calculate change @@ -306,6 +306,7 @@ private void persist() { JSONObject json = new JSONObject(); for (String symbol : this.portfolioStocksInfo.keySet()) { PortfolioStock item = this.portfolioStocksInfo.get(symbol); + assert item != null; if (item.hasData()) { try { json.put(symbol, item.toJson()); @@ -333,8 +334,7 @@ public HashMap getStocksForSymbols(List symbols) } private List getSortedSymbols() { - ArrayList symbols = new ArrayList<>(); - symbols.addAll(this.portfolioStocksInfo.keySet()); + ArrayList symbols = new ArrayList<>(this.portfolioStocksInfo.keySet()); try { // Ensure symbols beginning with ^ appear first @@ -358,7 +358,7 @@ public void updateStock(String symbol) { void removeUnused() { List symbols = new ArrayList<>(this.portfolioStocksInfo.keySet()); for (String symbol : symbols) { - String price = this.portfolioStocksInfo.get(symbol).getPrice(); + String price = Objects.requireNonNull(this.portfolioStocksInfo.get(symbol)).getPrice(); if ((price == null || price.equals("")) && !this.widgetsStockSymbols.contains(symbol)) { this.portfolioStocksInfo.remove(symbol); } diff --git a/src/main/java/nitezh/ministock/domain/StockQuote.java b/src/main/java/nitezh/ministock/domain/StockQuote.java index 349901b..d02c7fb 100644 --- a/src/main/java/nitezh/ministock/domain/StockQuote.java +++ b/src/main/java/nitezh/ministock/domain/StockQuote.java @@ -40,39 +40,12 @@ public class StockQuote { private final String volume; private final String name; - public StockQuote( - String symbol, - String price, - String change, - String percent, - String exchange, - String volume, - String name, - Locale locale) { - - this( - symbol, - price, - change, - percent, - exchange, - volume, - name, - null, - locale - ); + public StockQuote(String symbol, String price, String change, String percent, String exchange, String volume, String name, Locale locale) { + + this(symbol, price, change, percent, exchange, volume, name, null, locale); } - public StockQuote( - String symbol, - String price, - String change, - String percent, - String exchange, - String volume, - String name, - String previousPrice, - Locale locale) { + public StockQuote(String symbol, String price, String change, String percent, String exchange, String volume, String name, String previousPrice, Locale locale) { this.symbol = symbol; this.exchange = exchange; @@ -149,9 +122,7 @@ public StockQuote( } private boolean isNonEmptyNumber(String value) { - return !value.equals("N/A") - && !value.equals("") - && !value.equals("null"); + return !value.equals("N/A") && !value.equals("") && !value.equals("null"); } public String getSymbol() { diff --git a/src/main/java/nitezh/ministock/domain/StockQuoteRepository.java b/src/main/java/nitezh/ministock/domain/StockQuoteRepository.java index cdbc026..a4d05ed 100644 --- a/src/main/java/nitezh/ministock/domain/StockQuoteRepository.java +++ b/src/main/java/nitezh/ministock/domain/StockQuoteRepository.java @@ -38,6 +38,7 @@ of this software and associated documentation files (the "Software"), to deal import java.util.Iterator; import java.util.List; import java.util.Locale; +import java.util.Objects; import java.util.Set; import nitezh.ministock.Storage; @@ -95,9 +96,10 @@ private HashMap convertResponseQuotes(HashMap convertRequestSymbols(List symbols) { for (String symbol : symbols) { String newSymbol = symbol; for (String symbolToReplace : GOOGLE_SYMBOLS.inverse().keySet()) { - newSymbol = newSymbol.replace(symbolToReplace, GOOGLE_SYMBOLS.inverse().get(symbolToReplace)); + newSymbol = newSymbol.replace(symbolToReplace, Objects.requireNonNull(GOOGLE_SYMBOLS.inverse().get(symbolToReplace))); } newSymbols.add(newSymbol); } @@ -124,8 +126,7 @@ public HashMap getQuotes(List symbols, boolean noCac if (noCache) { Set widgetSymbols = this.widgetRepository.getWidgetsStockSymbols(); widgetSymbols.add("^DJI"); - widgetSymbols.addAll(new PortfolioStockRepository( - this.appStorage, this.widgetRepository).getStocks().keySet()); + widgetSymbols.addAll(new PortfolioStockRepository(this.appStorage, this.widgetRepository).getStocks().keySet()); quotes = getLiveQuotes(new ArrayList<>(widgetSymbols)); } @@ -138,8 +139,7 @@ public HashMap getQuotes(List symbols, boolean noCac } // Returns only quotes requested - @SuppressWarnings("unchecked") HashMap filteredQuotes = - (HashMap) quotes.clone(); + @SuppressWarnings("unchecked") HashMap filteredQuotes = (HashMap) quotes.clone(); filteredQuotes.keySet().retainAll(symbols); return filteredQuotes; } @@ -164,20 +164,11 @@ private HashMap loadQuotes() { String key; JSONObject details; - for (Iterator iter = savedQuotes.keys(); iter.hasNext(); ) { - key = (String) iter.next(); + for (Iterator iter = savedQuotes.keys(); iter.hasNext(); ) { + key = iter.next(); details = savedQuotes.getJSONObject(key); - quotes.put(key, new StockQuote( - details.getString("symbol"), - details.getString("price"), - details.getString("change"), - details.getString("percent"), - details.getString("exchange"), - details.getString("volume"), - details.getString("name"), - Locale.getDefault() - )); + quotes.put(key, new StockQuote(details.getString("symbol"), details.getString("price"), details.getString("change"), details.getString("percent"), details.getString("exchange"), details.getString("volume"), details.getString("name"), Locale.getDefault())); } } catch (Exception e) { quotes = new HashMap<>(); @@ -207,6 +198,7 @@ private void saveQuotes(HashMap quotes, String timeStamp) { StockQuote quote = quotes.get(symbol); try { + assert quote != null; savedQuotes.getJSONObject(symbol).put("symbol", quote.getSymbol()); savedQuotes.getJSONObject(symbol).put("price", quote.getPrice()); savedQuotes.getJSONObject(symbol).put("change", quote.getChange()); diff --git a/src/main/java/nitezh/ministock/utils/CurrencyTools.java b/src/main/java/nitezh/ministock/utils/CurrencyTools.java index cd582e8..5a07452 100644 --- a/src/main/java/nitezh/ministock/utils/CurrencyTools.java +++ b/src/main/java/nitezh/ministock/utils/CurrencyTools.java @@ -120,8 +120,7 @@ private static String getCurrencyForSymbol(String symbol) { currencyChar = charMap.get(codeMap.get(symbol.substring(index))); } - if (currencyChar == null) - currencyChar = "$"; + if (currencyChar == null) currencyChar = "$"; return currencyChar; } @@ -130,11 +129,10 @@ public static String addCurrencyToSymbol(String value, String symbol) { String currencySymbol = getCurrencyForSymbol(symbol); // £ needs division by 100 - if (currencySymbol.equals("£")) - try { - value = String.format(Locale.getDefault(), "%.0f", NumberTools.tryParseDouble(value) / 100); - } catch (Exception ignored) { - } + if (currencySymbol.equals("£")) try { + value = String.format(Locale.getDefault(), "%.0f", NumberTools.tryParseDouble(value) / 100); + } catch (Exception ignored) { + } // Move minus sign to front if present String prefix = ""; diff --git a/src/main/java/nitezh/ministock/utils/DateTools.java b/src/main/java/nitezh/ministock/utils/DateTools.java index c1e6838..a387bad 100644 --- a/src/main/java/nitezh/ministock/utils/DateTools.java +++ b/src/main/java/nitezh/ministock/utils/DateTools.java @@ -70,14 +70,8 @@ public static Date parseSimpleDate(String dateString) { } public static int compareToNow(Date date) { - Long now = new Date().getTime(); - if (date.getTime() > now) { - return 1; - } else if (date.getTime() < now) { - return -1; - } else { - return 0; - } + long now = new Date().getTime(); + return Long.compare(date.getTime(), now); } public static String getNowAsString() { @@ -85,9 +79,7 @@ public static String getNowAsString() { } public static String timeDigitPad(int c) { - if (c >= 10) - return String.valueOf(c); - else - return "0" + String.valueOf(c); + if (c >= 10) return String.valueOf(c); + else return "0" + String.valueOf(c); } } diff --git a/src/main/java/nitezh/ministock/utils/NumberTools.java b/src/main/java/nitezh/ministock/utils/NumberTools.java index 1b8a5ee..f5aef3b 100644 --- a/src/main/java/nitezh/ministock/utils/NumberTools.java +++ b/src/main/java/nitezh/ministock/utils/NumberTools.java @@ -113,8 +113,7 @@ public static String getTrimmedDouble(double number, int digits, Integer maxPrec } // Ignore maxPrecision = 0 - if (maxPrecision == null) - maxPrecision = precision; + if (maxPrecision == null) maxPrecision = precision; // Trim precision as necessary (max precision 4) return String.format("%." + Math.min(precision, maxPrecision) + "f", number); } @@ -144,8 +143,7 @@ else if (volume > 999999D) value = String.format(Locale.getDefault(), "%.0fM", volume / 1000000D); else if (volume > 999D) value = String.format(Locale.getDefault(), "%.0fK", volume / 1000D); - else - value = String.format(Locale.getDefault(), "%.0f", volume); + else value = String.format(Locale.getDefault(), "%.0f", volume); } catch (Exception ignored) { } return value; @@ -169,6 +167,7 @@ public static Double parseDouble(String value, Locale locale) throws ParseExcept // Double.parse handles '+' but NumberFormat.parse does not, so do it here Number number = format.parse(value.replace("+", "")); + assert number != null; return number.doubleValue(); } diff --git a/src/main/java/nitezh/ministock/utils/ReflectionTools.java b/src/main/java/nitezh/ministock/utils/ReflectionTools.java index 10b12b2..30ff008 100644 --- a/src/main/java/nitezh/ministock/utils/ReflectionTools.java +++ b/src/main/java/nitezh/ministock/utils/ReflectionTools.java @@ -31,7 +31,7 @@ public class ReflectionTools { private ReflectionTools() { } - + public static int getField(String name) { try { return R.id.class.getField(name).getInt(R.class); diff --git a/src/main/java/nitezh/ministock/utils/UrlDataTools.java b/src/main/java/nitezh/ministock/utils/UrlDataTools.java index 9a84a03..af80ceb 100644 --- a/src/main/java/nitezh/ministock/utils/UrlDataTools.java +++ b/src/main/java/nitezh/ministock/utils/UrlDataTools.java @@ -24,10 +24,13 @@ of this software and associated documentation files (the "Software"), to deal package nitezh.ministock.utils; +import android.util.Log; + import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; @@ -61,11 +64,15 @@ private static String getUrlData(String url) { } try { - URLConnection connection = new URL(url).openConnection(); + HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(); connection.setConnectTimeout(30000); connection.setReadTimeout(60000); - return inputStreamToString(connection.getInputStream()); + connection.setRequestMethod("GET"); + connection.setRequestProperty("User-Agent", "Ministocks - Stocks Widget"); + InputStream inputStream = connection.getInputStream(); + return inputStreamToString(inputStream); } catch (IOException ignored) { + Log.i("TAG", "getUrlData: " + ignored); } return null; } diff --git a/src/main/java/nitezh/ministock/utils/VersionTools.java b/src/main/java/nitezh/ministock/utils/VersionTools.java index e371095..2c31b46 100644 --- a/src/main/java/nitezh/ministock/utils/VersionTools.java +++ b/src/main/java/nitezh/ministock/utils/VersionTools.java @@ -27,7 +27,7 @@ of this software and associated documentation files (the "Software"), to deal public class VersionTools { - public static final String BUILD = "80"; + public static final String BUILD = "81"; private VersionTools() { }