mirror of
https://github.com/CatimaLoyalty/Android.git
synced 2026-04-04 15:43:46 -04:00
Merge branch 'master' of github.com:TheLastProject/loyalty-card-locker into feature/power_screen_widgets
This commit is contained in:
@@ -4,30 +4,29 @@ import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.os.AsyncTask;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
import com.google.zxing.MultiFormatWriter;
|
||||
import com.google.zxing.WriterException;
|
||||
import com.google.zxing.common.BitMatrix;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
import protect.card_locker.async.CompatCallable;
|
||||
|
||||
/**
|
||||
* This task will generate a barcode and load it into an ImageView.
|
||||
* Only a weak reference of the ImageView is kept, so this class will not
|
||||
* prevent the ImageView from being garbage collected.
|
||||
*/
|
||||
class BarcodeImageWriterTask extends AsyncTask<Void, Void, Bitmap>
|
||||
{
|
||||
public class BarcodeImageWriterTask implements CompatCallable<Bitmap> {
|
||||
private static final String TAG = "Catima";
|
||||
|
||||
private static final int IS_VALID = 999;
|
||||
private Context mContext;
|
||||
private final Context mContext;
|
||||
private boolean isSuccesful;
|
||||
|
||||
// When drawn in a smaller window 1D barcodes for some reason end up
|
||||
@@ -44,10 +43,11 @@ class BarcodeImageWriterTask extends AsyncTask<Void, Void, Bitmap>
|
||||
private final boolean showFallback;
|
||||
private final Runnable callback;
|
||||
|
||||
BarcodeImageWriterTask(Context context, ImageView imageView, String cardIdString,
|
||||
CatimaBarcode barcodeFormat, TextView textView,
|
||||
boolean showFallback, Runnable callback)
|
||||
{
|
||||
BarcodeImageWriterTask(
|
||||
Context context, ImageView imageView, String cardIdString,
|
||||
CatimaBarcode barcodeFormat, TextView textView,
|
||||
boolean showFallback, Runnable callback
|
||||
) {
|
||||
mContext = context;
|
||||
|
||||
isSuccesful = true;
|
||||
@@ -62,26 +62,21 @@ class BarcodeImageWriterTask extends AsyncTask<Void, Void, Bitmap>
|
||||
|
||||
final int MAX_WIDTH = getMaxWidth(format);
|
||||
|
||||
if(imageView.getWidth() < MAX_WIDTH)
|
||||
{
|
||||
if (imageView.getWidth() < MAX_WIDTH) {
|
||||
imageHeight = imageView.getHeight();
|
||||
imageWidth = imageView.getWidth();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// Scale down the image to reduce the memory needed to produce it
|
||||
imageWidth = MAX_WIDTH;
|
||||
double ratio = (double)MAX_WIDTH / (double)imageView.getWidth();
|
||||
imageHeight = (int)(imageView.getHeight() * ratio);
|
||||
double ratio = (double) MAX_WIDTH / (double) imageView.getWidth();
|
||||
imageHeight = (int) (imageView.getHeight() * ratio);
|
||||
}
|
||||
|
||||
this.showFallback = showFallback;
|
||||
}
|
||||
|
||||
private int getMaxWidth(CatimaBarcode format)
|
||||
{
|
||||
switch(format.format())
|
||||
{
|
||||
private int getMaxWidth(CatimaBarcode format) {
|
||||
switch (format.format()) {
|
||||
// 2D barcodes
|
||||
case AZTEC:
|
||||
case DATA_MATRIX:
|
||||
@@ -108,10 +103,8 @@ class BarcodeImageWriterTask extends AsyncTask<Void, Void, Bitmap>
|
||||
}
|
||||
}
|
||||
|
||||
private String getFallbackString(CatimaBarcode format)
|
||||
{
|
||||
switch(format.format())
|
||||
{
|
||||
private String getFallbackString(CatimaBarcode format) {
|
||||
switch (format.format()) {
|
||||
// 2D barcodes
|
||||
case AZTEC:
|
||||
return "AZTEC";
|
||||
@@ -144,23 +137,17 @@ class BarcodeImageWriterTask extends AsyncTask<Void, Void, Bitmap>
|
||||
}
|
||||
}
|
||||
|
||||
private Bitmap generate()
|
||||
{
|
||||
if (cardId.isEmpty())
|
||||
{
|
||||
private Bitmap generate() {
|
||||
if (cardId.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
MultiFormatWriter writer = new MultiFormatWriter();
|
||||
BitMatrix bitMatrix;
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
try {
|
||||
try {
|
||||
bitMatrix = writer.encode(cardId, format.format(), imageWidth, imageHeight, null);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
} catch (Exception e) {
|
||||
// Cast a wider net here and catch any exception, as there are some
|
||||
// cases where an encoder may fail if the data is invalid for the
|
||||
// barcode type. If this happens, we want to fail gracefully.
|
||||
@@ -175,11 +162,9 @@ class BarcodeImageWriterTask extends AsyncTask<Void, Void, Bitmap>
|
||||
|
||||
int[] pixels = new int[bitMatrixWidth * bitMatrixHeight];
|
||||
|
||||
for (int y = 0; y < bitMatrixHeight; y++)
|
||||
{
|
||||
for (int y = 0; y < bitMatrixHeight; y++) {
|
||||
int offset = y * bitMatrixWidth;
|
||||
for (int x = 0; x < bitMatrixWidth; x++)
|
||||
{
|
||||
for (int x = 0; x < bitMatrixWidth; x++) {
|
||||
int color = bitMatrix.get(x, y) ? BLACK : WHITE;
|
||||
pixels[offset + x] = color;
|
||||
}
|
||||
@@ -199,19 +184,14 @@ class BarcodeImageWriterTask extends AsyncTask<Void, Void, Bitmap>
|
||||
int widthScale = imageWidth / bitMatrixHeight;
|
||||
int scalingFactor = Math.min(heightScale, widthScale);
|
||||
|
||||
if(scalingFactor > 1)
|
||||
{
|
||||
if (scalingFactor > 1) {
|
||||
bitmap = Bitmap.createScaledBitmap(bitmap, bitMatrixWidth * scalingFactor, bitMatrixHeight * scalingFactor, false);
|
||||
}
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
catch (WriterException e)
|
||||
{
|
||||
} catch (WriterException e) {
|
||||
Log.e(TAG, "Failed to generate barcode of type " + format + ": " + cardId, e);
|
||||
}
|
||||
catch(OutOfMemoryError e)
|
||||
{
|
||||
} catch (OutOfMemoryError e) {
|
||||
Log.w(TAG, "Insufficient memory to render barcode, "
|
||||
+ imageWidth + "x" + imageHeight + ", " + format.name()
|
||||
+ ", length=" + cardId.length(), e);
|
||||
@@ -220,29 +200,36 @@ class BarcodeImageWriterTask extends AsyncTask<Void, Void, Bitmap>
|
||||
return null;
|
||||
}
|
||||
|
||||
public Bitmap doInBackground(Void... params)
|
||||
{
|
||||
Bitmap bitmap = generate();
|
||||
public Bitmap doInBackground(Void... params) {
|
||||
// Only do the hard tasks if we've not already been cancelled
|
||||
if (!Thread.currentThread().isInterrupted()) {
|
||||
Bitmap bitmap = generate();
|
||||
|
||||
if (bitmap == null) {
|
||||
isSuccesful = false;
|
||||
if (bitmap == null) {
|
||||
isSuccesful = false;
|
||||
|
||||
if (showFallback) {
|
||||
Log.i(TAG, "Barcode generation failed, generating fallback...");
|
||||
cardId = getFallbackString(format);
|
||||
bitmap = generate();
|
||||
if (showFallback && !Thread.currentThread().isInterrupted()) {
|
||||
Log.i(TAG, "Barcode generation failed, generating fallback...");
|
||||
cardId = getFallbackString(format);
|
||||
bitmap = generate();
|
||||
return bitmap;
|
||||
}
|
||||
} else {
|
||||
return bitmap;
|
||||
}
|
||||
}
|
||||
|
||||
return bitmap;
|
||||
// We've been interrupted - create a empty fallback
|
||||
Bitmap.Config config = Bitmap.Config.ARGB_8888;
|
||||
return Bitmap.createBitmap(imageWidth, imageHeight, config);
|
||||
}
|
||||
|
||||
protected void onPostExecute(Bitmap result)
|
||||
{
|
||||
public void onPostExecute(Object castResult) {
|
||||
Bitmap result = (Bitmap) castResult;
|
||||
|
||||
Log.i(TAG, "Finished generating barcode image of type " + format + ": " + cardId);
|
||||
ImageView imageView = imageViewReference.get();
|
||||
if(imageView == null)
|
||||
{
|
||||
if (imageView == null) {
|
||||
// The ImageView no longer exists, nothing to do
|
||||
return;
|
||||
}
|
||||
@@ -255,8 +242,7 @@ class BarcodeImageWriterTask extends AsyncTask<Void, Void, Bitmap>
|
||||
imageView.setContentDescription(mContext.getString(R.string.barcodeImageDescriptionWithType, formatPrettyName));
|
||||
TextView textView = textViewReference.get();
|
||||
|
||||
if(result != null)
|
||||
{
|
||||
if (result != null) {
|
||||
Log.i(TAG, "Displaying barcode");
|
||||
imageView.setVisibility(View.VISIBLE);
|
||||
|
||||
@@ -270,9 +256,7 @@ class BarcodeImageWriterTask extends AsyncTask<Void, Void, Bitmap>
|
||||
textView.setVisibility(View.VISIBLE);
|
||||
textView.setText(formatPrettyName);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Log.i(TAG, "Barcode generation failed, removing image from display");
|
||||
imageView.setVisibility(View.GONE);
|
||||
if (textView != null) {
|
||||
@@ -284,4 +268,19 @@ class BarcodeImageWriterTask extends AsyncTask<Void, Void, Bitmap>
|
||||
callback.run();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPreExecute() {
|
||||
// No Action
|
||||
}
|
||||
|
||||
/**
|
||||
* Provided to comply with Callable while keeping the original Syntax of AsyncTask
|
||||
*
|
||||
* @return generated Bitmap
|
||||
*/
|
||||
@Override
|
||||
public Bitmap call() {
|
||||
return doInBackground();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,9 @@ package protect.card_locker;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
import android.view.MenuItem;
|
||||
@@ -16,24 +17,21 @@ import android.widget.Toast;
|
||||
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
|
||||
import protect.card_locker.async.TaskHandler;
|
||||
|
||||
/**
|
||||
* This activity is callable and will allow a user to enter
|
||||
* barcode data and generate all barcodes possible for
|
||||
* the data. The user may then select any barcode, where its
|
||||
* data and type will be returned to the caller.
|
||||
*/
|
||||
public class BarcodeSelectorActivity extends CatimaAppCompatActivity
|
||||
{
|
||||
public class BarcodeSelectorActivity extends CatimaAppCompatActivity {
|
||||
private static final String TAG = "Catima";
|
||||
|
||||
// Result this activity will return
|
||||
@@ -41,19 +39,21 @@ public class BarcodeSelectorActivity extends CatimaAppCompatActivity
|
||||
public static final String BARCODE_FORMAT = "format";
|
||||
|
||||
private Map<String, Pair<Integer, Integer>> barcodeViewMap;
|
||||
private LinkedList<AsyncTask> barcodeGeneratorTasks = new LinkedList<>();
|
||||
|
||||
final private TaskHandler mTasks = new TaskHandler();
|
||||
|
||||
private final Handler typingDelayHandler = new Handler(Looper.getMainLooper());
|
||||
public static final Integer INPUT_DELAY = 250;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setTitle(R.string.selectBarcodeTitle);
|
||||
setContentView(R.layout.barcode_selector_activity);
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
if(actionBar != null)
|
||||
{
|
||||
if (actionBar != null) {
|
||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
|
||||
@@ -72,26 +72,31 @@ public class BarcodeSelectorActivity extends CatimaAppCompatActivity
|
||||
barcodeViewMap.put(BarcodeFormat.UPC_E.name(), new Pair<>(R.id.upceBarcode, R.id.upceBarcodeText));
|
||||
|
||||
EditText cardId = findViewById(R.id.cardId);
|
||||
cardId.addTextChangedListener(new SimpleTextWatcher()
|
||||
{
|
||||
|
||||
cardId.addTextChangedListener(new SimpleTextWatcher() {
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count)
|
||||
{
|
||||
Log.d(TAG, "Entered text: " + s);
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
// Delay the input processing so we avoid overload
|
||||
typingDelayHandler.removeCallbacksAndMessages(null);
|
||||
|
||||
generateBarcodes(s.toString());
|
||||
typingDelayHandler.postDelayed(() -> {
|
||||
Log.d(TAG, "Entered text: " + s);
|
||||
|
||||
View noBarcodeButtonView = findViewById(R.id.noBarcode);
|
||||
setButtonListener(noBarcodeButtonView, s.toString());
|
||||
noBarcodeButtonView.setEnabled(s.length() > 0);
|
||||
runOnUiThread(() -> {
|
||||
generateBarcodes(s.toString());
|
||||
|
||||
View noBarcodeButtonView = findViewById(R.id.noBarcode);
|
||||
setButtonListener(noBarcodeButtonView, s.toString());
|
||||
noBarcodeButtonView.setEnabled(s.length() > 0);
|
||||
});
|
||||
}, INPUT_DELAY);
|
||||
}
|
||||
});
|
||||
|
||||
final Bundle b = getIntent().getExtras();
|
||||
final String initialCardId = b != null ? b.getString("initialCardId") : null;
|
||||
|
||||
if(initialCardId != null)
|
||||
{
|
||||
if (initialCardId != null) {
|
||||
cardId.setText(initialCardId);
|
||||
} else {
|
||||
generateBarcodes("");
|
||||
@@ -99,24 +104,19 @@ public class BarcodeSelectorActivity extends CatimaAppCompatActivity
|
||||
}
|
||||
|
||||
private void generateBarcodes(String value) {
|
||||
// Stop any async tasks which may not have been started yet
|
||||
for(AsyncTask task : barcodeGeneratorTasks)
|
||||
{
|
||||
task.cancel(false);
|
||||
}
|
||||
barcodeGeneratorTasks.clear();
|
||||
// Attempt to stop any async tasks which may not have been started yet
|
||||
// TODO this can be very much optimized by only generating Barcodes visible to the User
|
||||
mTasks.flushTaskList(TaskHandler.TYPE.BARCODE, true, false, false);
|
||||
|
||||
// Update barcodes
|
||||
for(Map.Entry<String, Pair<Integer, Integer>> entry : barcodeViewMap.entrySet())
|
||||
{
|
||||
for (Map.Entry<String, Pair<Integer, Integer>> entry : barcodeViewMap.entrySet()) {
|
||||
ImageView image = findViewById(entry.getValue().first);
|
||||
TextView text = findViewById(entry.getValue().second);
|
||||
createBarcodeOption(image, entry.getKey(), value, text);
|
||||
}
|
||||
}
|
||||
|
||||
private void setButtonListener(final View button, final String cardId)
|
||||
{
|
||||
private void setButtonListener(final View button, final String cardId) {
|
||||
button.setOnClickListener(view -> {
|
||||
Log.d(TAG, "Selected no barcode");
|
||||
Intent result = new Intent();
|
||||
@@ -127,8 +127,7 @@ public class BarcodeSelectorActivity extends CatimaAppCompatActivity
|
||||
});
|
||||
}
|
||||
|
||||
private void createBarcodeOption(final ImageView image, final String formatType, final String cardId, final TextView text)
|
||||
{
|
||||
private void createBarcodeOption(final ImageView image, final String formatType, final String cardId, final TextView text) {
|
||||
final CatimaBarcode format = CatimaBarcode.fromName(formatType);
|
||||
|
||||
image.setImageBitmap(null);
|
||||
@@ -147,40 +146,32 @@ public class BarcodeSelectorActivity extends CatimaAppCompatActivity
|
||||
finish();
|
||||
});
|
||||
|
||||
if(image.getHeight() == 0)
|
||||
{
|
||||
if (image.getHeight() == 0) {
|
||||
// The size of the ImageView is not yet available as it has not
|
||||
// yet been drawn. Wait for it to be drawn so the size is available.
|
||||
image.getViewTreeObserver().addOnGlobalLayoutListener(
|
||||
new ViewTreeObserver.OnGlobalLayoutListener()
|
||||
{
|
||||
@Override
|
||||
public void onGlobalLayout()
|
||||
{
|
||||
Log.d(TAG, "Global layout finished, type: + " + formatType + ", width: " + image.getWidth());
|
||||
image.getViewTreeObserver().removeOnGlobalLayoutListener(this);
|
||||
new ViewTreeObserver.OnGlobalLayoutListener() {
|
||||
@Override
|
||||
public void onGlobalLayout() {
|
||||
Log.d(TAG, "Global layout finished, type: + " + formatType + ", width: " + image.getWidth());
|
||||
image.getViewTreeObserver().removeOnGlobalLayoutListener(this);
|
||||
|
||||
Log.d(TAG, "Generating barcode for type " + formatType);
|
||||
BarcodeImageWriterTask task = new BarcodeImageWriterTask(getApplicationContext(), image, cardId, format, text, true, null);
|
||||
barcodeGeneratorTasks.add(task);
|
||||
task.execute();
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.d(TAG, "Generating barcode for type " + formatType);
|
||||
|
||||
BarcodeImageWriterTask barcodeWriter = new BarcodeImageWriterTask(getApplicationContext(), image, cardId, format, text, true, null);
|
||||
mTasks.executeTask(TaskHandler.TYPE.BARCODE, barcodeWriter);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Log.d(TAG, "Generating barcode for type " + formatType);
|
||||
BarcodeImageWriterTask task = new BarcodeImageWriterTask(getApplicationContext(), image, cardId, format, text, true, null);
|
||||
barcodeGeneratorTasks.add(task);
|
||||
task.execute();
|
||||
BarcodeImageWriterTask barcodeWriter = new BarcodeImageWriterTask(getApplicationContext(), image, cardId, format, text, true, null);
|
||||
mTasks.executeTask(TaskHandler.TYPE.BARCODE, barcodeWriter);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item)
|
||||
{
|
||||
if (item.getItemId() == android.R.id.home)
|
||||
{
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
setResult(Activity.RESULT_CANCELED);
|
||||
finish();
|
||||
return true;
|
||||
|
||||
@@ -8,6 +8,7 @@ import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteException;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.math.BigDecimal;
|
||||
@@ -21,7 +22,7 @@ public class DBHelper extends SQLiteOpenHelper
|
||||
{
|
||||
public static final String DATABASE_NAME = "Catima.db";
|
||||
public static final int ORIGINAL_DATABASE_VERSION = 1;
|
||||
public static final int DATABASE_VERSION = 13;
|
||||
public static final int DATABASE_VERSION = 14;
|
||||
|
||||
public static class LoyaltyCardDbGroups
|
||||
{
|
||||
@@ -46,6 +47,7 @@ public class DBHelper extends SQLiteOpenHelper
|
||||
public static final String BARCODE_TYPE = "barcodetype";
|
||||
public static final String STAR_STATUS = "starstatus";
|
||||
public static final String LAST_USED = "lastused";
|
||||
public static final String ZOOM_LEVEL = "zoomlevel";
|
||||
}
|
||||
|
||||
public static class LoyaltyCardDbIdsGroups
|
||||
@@ -105,7 +107,8 @@ public class DBHelper extends SQLiteOpenHelper
|
||||
LoyaltyCardDbIds.BARCODE_ID + " TEXT," +
|
||||
LoyaltyCardDbIds.BARCODE_TYPE + " TEXT," +
|
||||
LoyaltyCardDbIds.STAR_STATUS + " INTEGER DEFAULT '0'," +
|
||||
LoyaltyCardDbIds.LAST_USED + " INTEGER DEFAULT '0')");
|
||||
LoyaltyCardDbIds.LAST_USED + " INTEGER DEFAULT '0', "+
|
||||
LoyaltyCardDbIds.ZOOM_LEVEL + " INTEGER DEFAULT '100' )");
|
||||
|
||||
// create associative table for cards in groups
|
||||
db.execSQL("CREATE TABLE " + LoyaltyCardDbIdsGroups.TABLE + "(" +
|
||||
@@ -119,6 +122,7 @@ public class DBHelper extends SQLiteOpenHelper
|
||||
"tokenize=unicode61);");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
|
||||
{
|
||||
@@ -290,8 +294,10 @@ public class DBHelper extends SQLiteOpenHelper
|
||||
cursor.moveToFirst();
|
||||
|
||||
while (cursor.moveToNext()) {
|
||||
LoyaltyCard loyaltyCard = LoyaltyCard.toLoyaltyCard(cursor);
|
||||
insertFTS(db, loyaltyCard.id, loyaltyCard.store, loyaltyCard.note);
|
||||
int id = cursor.getInt(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.ID));
|
||||
String store = cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.STORE));
|
||||
String note = cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.NOTE));
|
||||
insertFTS(db, id, store, note);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -302,16 +308,25 @@ public class DBHelper extends SQLiteOpenHelper
|
||||
Cursor cursor = db.rawQuery("SELECT * FROM " + LoyaltyCardDbIds.TABLE + ";", null, null);
|
||||
|
||||
if (cursor.moveToFirst()) {
|
||||
LoyaltyCard loyaltyCard = LoyaltyCard.toLoyaltyCard(cursor);
|
||||
insertFTS(db, loyaltyCard.id, loyaltyCard.store, loyaltyCard.note);
|
||||
int id = cursor.getInt(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.ID));
|
||||
String store = cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.STORE));
|
||||
String note = cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.NOTE));
|
||||
insertFTS(db, id, store, note);
|
||||
|
||||
while (cursor.moveToNext()) {
|
||||
loyaltyCard = LoyaltyCard.toLoyaltyCard(cursor);
|
||||
insertFTS(db, loyaltyCard.id, loyaltyCard.store, loyaltyCard.note);
|
||||
id = cursor.getInt(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.ID));
|
||||
store = cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.STORE));
|
||||
note = cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.NOTE));
|
||||
insertFTS(db, id, store, note);
|
||||
}
|
||||
}
|
||||
cursor.close();
|
||||
}
|
||||
|
||||
if(oldVersion < 14 && newVersion >= 14){
|
||||
db.execSQL("ALTER TABLE " + LoyaltyCardDbIds.TABLE
|
||||
+ " ADD COLUMN " + LoyaltyCardDbIds.ZOOM_LEVEL + " INTEGER DEFAULT '100' ");
|
||||
}
|
||||
}
|
||||
|
||||
private ContentValues generateFTSContentValues(final int id, final String store, final String note) {
|
||||
@@ -508,6 +523,18 @@ public class DBHelper extends SQLiteOpenHelper
|
||||
return (rowsUpdated == 1);
|
||||
}
|
||||
|
||||
public boolean updateLoyaltyCardZoomLevel(int loyaltyCardId, int zoomLevel){
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
ContentValues contentValues = new ContentValues();
|
||||
contentValues.put(LoyaltyCardDbIds.ZOOM_LEVEL,zoomLevel);
|
||||
Log.d("updateLoyaltyCardZLevel","Card Id = "+loyaltyCardId+" Zoom level= "+zoomLevel);
|
||||
int rowsUpdated = db.update(LoyaltyCardDbIds.TABLE,contentValues,
|
||||
whereAttrs(LoyaltyCardDbIds.ID),
|
||||
withArgs(loyaltyCardId));
|
||||
Log.d("updateLoyaltyCardZLevel","Rows changed = "+rowsUpdated);
|
||||
return (rowsUpdated == 1);
|
||||
}
|
||||
|
||||
public LoyaltyCard getLoyaltyCard(final int id)
|
||||
{
|
||||
SQLiteDatabase db = getReadableDatabase();
|
||||
|
||||
@@ -6,7 +6,6 @@ import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.text.InputType;
|
||||
import android.util.Log;
|
||||
@@ -32,11 +31,12 @@ import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import protect.card_locker.async.TaskHandler;
|
||||
import protect.card_locker.importexport.DataFormat;
|
||||
import protect.card_locker.importexport.ImportExportResult;
|
||||
|
||||
public class ImportExportActivity extends CatimaAppCompatActivity
|
||||
{
|
||||
public class ImportExportActivity extends CatimaAppCompatActivity {
|
||||
private static final String TAG = "Catima";
|
||||
|
||||
private static final int PERMISSIONS_EXTERNAL_STORAGE = 1;
|
||||
@@ -50,17 +50,17 @@ public class ImportExportActivity extends CatimaAppCompatActivity
|
||||
private DataFormat importDataFormat;
|
||||
private String exportPassword;
|
||||
|
||||
final private TaskHandler mTasks = new TaskHandler();
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setTitle(R.string.importExport);
|
||||
setContentView(R.layout.import_export_activity);
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
if(actionBar != null)
|
||||
{
|
||||
if (actionBar != null) {
|
||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
|
||||
@@ -69,12 +69,11 @@ public class ImportExportActivity extends CatimaAppCompatActivity
|
||||
|
||||
if (ContextCompat.checkSelfPermission(ImportExportActivity.this,
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED ||
|
||||
ContextCompat.checkSelfPermission(ImportExportActivity.this,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
|
||||
{
|
||||
ContextCompat.checkSelfPermission(ImportExportActivity.this,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
||||
ActivityCompat.requestPermissions(ImportExportActivity.this,
|
||||
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE},
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE},
|
||||
PERMISSIONS_EXTERNAL_STORAGE);
|
||||
}
|
||||
|
||||
@@ -85,16 +84,14 @@ public class ImportExportActivity extends CatimaAppCompatActivity
|
||||
intentCreateDocumentAction.putExtra(Intent.EXTRA_TITLE, "catima.zip");
|
||||
|
||||
Button exportButton = findViewById(R.id.exportButton);
|
||||
exportButton.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
exportButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
public void onClick(View v) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(ImportExportActivity.this);
|
||||
builder.setTitle(R.string.exportPassword);
|
||||
|
||||
FrameLayout container = new FrameLayout(ImportExportActivity.this);
|
||||
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
params.leftMargin = 50;
|
||||
params.rightMargin = 50;
|
||||
|
||||
@@ -121,11 +118,9 @@ public class ImportExportActivity extends CatimaAppCompatActivity
|
||||
intentGetContentAction.setType("*/*");
|
||||
|
||||
Button importFilesystem = findViewById(R.id.importOptionFilesystemButton);
|
||||
importFilesystem.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
importFilesystem.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
public void onClick(View v) {
|
||||
chooseImportType(intentGetContentAction);
|
||||
}
|
||||
});
|
||||
@@ -134,11 +129,9 @@ public class ImportExportActivity extends CatimaAppCompatActivity
|
||||
final Intent intentPickAction = new Intent(Intent.ACTION_PICK);
|
||||
|
||||
Button importApplication = findViewById(R.id.importOptionApplicationButton);
|
||||
importApplication.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
importApplication.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
public void onClick(View v) {
|
||||
chooseImportType(intentPickAction);
|
||||
}
|
||||
});
|
||||
@@ -200,24 +193,22 @@ public class ImportExportActivity extends CatimaAppCompatActivity
|
||||
.setTitle(importAlertTitle)
|
||||
.setMessage(importAlertMessage)
|
||||
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
chooseFileWithIntent(baseIntent, IMPORT);
|
||||
}
|
||||
})
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
chooseFileWithIntent(baseIntent, IMPORT);
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.show();
|
||||
});
|
||||
builder.show();
|
||||
}
|
||||
|
||||
private void startImport(final InputStream target, final Uri targetUri, final DataFormat dataFormat, final char[] password, final boolean closeWhenDone)
|
||||
{
|
||||
ImportExportTask.TaskCompleteListener listener = new ImportExportTask.TaskCompleteListener()
|
||||
{
|
||||
private void startImport(final InputStream target, final Uri targetUri, final DataFormat dataFormat, final char[] password, final boolean closeWhenDone) {
|
||||
mTasks.flushTaskList(TaskHandler.TYPE.IMPORT, true, false, false);
|
||||
ImportExportTask.TaskCompleteListener listener = new ImportExportTask.TaskCompleteListener() {
|
||||
@Override
|
||||
public void onTaskComplete(ImportExportResult result, DataFormat dataFormat)
|
||||
{
|
||||
public void onTaskComplete(ImportExportResult result, DataFormat dataFormat) {
|
||||
onImportComplete(result, targetUri, dataFormat);
|
||||
if (closeWhenDone) {
|
||||
try {
|
||||
@@ -231,13 +222,12 @@ public class ImportExportActivity extends CatimaAppCompatActivity
|
||||
|
||||
importExporter = new ImportExportTask(ImportExportActivity.this,
|
||||
dataFormat, target, password, listener);
|
||||
importExporter.execute();
|
||||
mTasks.executeTask(TaskHandler.TYPE.IMPORT, importExporter);
|
||||
}
|
||||
|
||||
private void startExport(final OutputStream target, final Uri targetUri,char[] password, final boolean closeWhenDone)
|
||||
{
|
||||
ImportExportTask.TaskCompleteListener listener = new ImportExportTask.TaskCompleteListener()
|
||||
{
|
||||
private void startExport(final OutputStream target, final Uri targetUri, char[] password, final boolean closeWhenDone) {
|
||||
mTasks.flushTaskList(TaskHandler.TYPE.EXPORT, true, false, false);
|
||||
ImportExportTask.TaskCompleteListener listener = new ImportExportTask.TaskCompleteListener() {
|
||||
@Override
|
||||
public void onTaskComplete(ImportExportResult result, DataFormat dataFormat) {
|
||||
onExportComplete(result, targetUri);
|
||||
@@ -252,8 +242,8 @@ public class ImportExportActivity extends CatimaAppCompatActivity
|
||||
};
|
||||
|
||||
importExporter = new ImportExportTask(ImportExportActivity.this,
|
||||
DataFormat.Catima, target,password, listener);
|
||||
importExporter.execute();
|
||||
DataFormat.Catima, target, password, listener);
|
||||
mTasks.executeTask(TaskHandler.TYPE.EXPORT, importExporter);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -281,22 +271,17 @@ public class ImportExportActivity extends CatimaAppCompatActivity
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy()
|
||||
{
|
||||
if(importExporter != null && importExporter.getStatus() != AsyncTask.Status.RUNNING)
|
||||
{
|
||||
importExporter.cancel(true);
|
||||
}
|
||||
protected void onDestroy() {
|
||||
mTasks.flushTaskList(TaskHandler.TYPE.IMPORT, true, false, false);
|
||||
mTasks.flushTaskList(TaskHandler.TYPE.EXPORT, true, false, false);
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item)
|
||||
{
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
int id = item.getItemId();
|
||||
|
||||
if(id == android.R.id.home)
|
||||
{
|
||||
if (id == android.R.id.home) {
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
@@ -330,13 +315,10 @@ public class ImportExportActivity extends CatimaAppCompatActivity
|
||||
|
||||
int messageId;
|
||||
|
||||
if (result == ImportExportResult.Success)
|
||||
{
|
||||
if (result == ImportExportResult.Success) {
|
||||
builder.setTitle(R.string.importSuccessfulTitle);
|
||||
messageId = R.string.importSuccessful;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
builder.setTitle(R.string.importFailedTitle);
|
||||
messageId = R.string.importFailed;
|
||||
}
|
||||
@@ -344,11 +326,9 @@ public class ImportExportActivity extends CatimaAppCompatActivity
|
||||
final String message = getResources().getString(messageId);
|
||||
|
||||
builder.setMessage(message);
|
||||
builder.setNeutralButton(R.string.ok, new DialogInterface.OnClickListener()
|
||||
{
|
||||
builder.setNeutralButton(R.string.ok, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
@@ -356,19 +336,15 @@ public class ImportExportActivity extends CatimaAppCompatActivity
|
||||
builder.create().show();
|
||||
}
|
||||
|
||||
private void onExportComplete(ImportExportResult result, final Uri path)
|
||||
{
|
||||
private void onExportComplete(ImportExportResult result, final Uri path) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
|
||||
int messageId;
|
||||
|
||||
if(result == ImportExportResult.Success)
|
||||
{
|
||||
if (result == ImportExportResult.Success) {
|
||||
builder.setTitle(R.string.exportSuccessfulTitle);
|
||||
messageId = R.string.exportSuccessful;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
builder.setTitle(R.string.exportFailedTitle);
|
||||
messageId = R.string.exportFailed;
|
||||
}
|
||||
@@ -378,8 +354,7 @@ public class ImportExportActivity extends CatimaAppCompatActivity
|
||||
builder.setMessage(message);
|
||||
builder.setNeutralButton(R.string.ok, (dialog, which) -> dialog.dismiss());
|
||||
|
||||
if(result == ImportExportResult.Success)
|
||||
{
|
||||
if (result == ImportExportResult.Success) {
|
||||
final CharSequence sendLabel = ImportExportActivity.this.getResources().getText(R.string.sendLabel);
|
||||
|
||||
builder.setPositiveButton(sendLabel, (dialog, which) -> {
|
||||
@@ -400,58 +375,42 @@ public class ImportExportActivity extends CatimaAppCompatActivity
|
||||
builder.create().show();
|
||||
}
|
||||
|
||||
private void chooseFileWithIntent(Intent intent, int requestCode)
|
||||
{
|
||||
try
|
||||
{
|
||||
private void chooseFileWithIntent(Intent intent, int requestCode) {
|
||||
try {
|
||||
startActivityForResult(intent, requestCode);
|
||||
}
|
||||
catch (ActivityNotFoundException e)
|
||||
{
|
||||
} catch (ActivityNotFoundException e) {
|
||||
Toast.makeText(getApplicationContext(), R.string.failedOpeningFileManager, Toast.LENGTH_LONG).show();
|
||||
Log.e(TAG, "No activity found to handle intent", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void activityResultParser(int requestCode, int resultCode, Uri uri, char[] password) {
|
||||
if (resultCode != RESULT_OK)
|
||||
{
|
||||
if (resultCode != RESULT_OK) {
|
||||
Log.w(TAG, "Failed onActivityResult(), result=" + resultCode);
|
||||
return;
|
||||
}
|
||||
|
||||
if(uri == null)
|
||||
{
|
||||
if (uri == null) {
|
||||
Log.e(TAG, "Activity returned a NULL URI");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (requestCode == CHOOSE_EXPORT_LOCATION)
|
||||
{
|
||||
try {
|
||||
if (requestCode == CHOOSE_EXPORT_LOCATION) {
|
||||
|
||||
OutputStream writer;
|
||||
if (uri.getScheme() != null)
|
||||
{
|
||||
if (uri.getScheme() != null) {
|
||||
writer = getContentResolver().openOutputStream(uri);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
writer = new FileOutputStream(new File(uri.toString()));
|
||||
}
|
||||
Log.e(TAG, "Starting file export with: " + uri.toString());
|
||||
startExport(writer, uri,exportPassword.toCharArray(),true);
|
||||
}
|
||||
else
|
||||
{
|
||||
startExport(writer, uri, exportPassword.toCharArray(), true);
|
||||
} else {
|
||||
InputStream reader;
|
||||
if(uri.getScheme() != null)
|
||||
{
|
||||
if (uri.getScheme() != null) {
|
||||
reader = getContentResolver().openInputStream(uri);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
reader = new FileInputStream(new File(uri.toString()));
|
||||
}
|
||||
|
||||
@@ -459,28 +418,21 @@ public class ImportExportActivity extends CatimaAppCompatActivity
|
||||
|
||||
startImport(reader, uri, importDataFormat, password, true);
|
||||
}
|
||||
}
|
||||
catch(IOException e)
|
||||
{
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Failed to import/export file: " + uri.toString(), e);
|
||||
if (requestCode == CHOOSE_EXPORT_LOCATION)
|
||||
{
|
||||
if (requestCode == CHOOSE_EXPORT_LOCATION) {
|
||||
onExportComplete(ImportExportResult.GenericFailure, uri);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
onImportComplete(ImportExportResult.GenericFailure, uri, importDataFormat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data)
|
||||
{
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
|
||||
if(data == null)
|
||||
{
|
||||
if (data == null) {
|
||||
Log.e(TAG, "Activity returned NULL data");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import android.app.Activity;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.AsyncTask;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -13,13 +12,13 @@ import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import protect.card_locker.async.CompatCallable;
|
||||
import protect.card_locker.importexport.DataFormat;
|
||||
import protect.card_locker.importexport.ImportExportResult;
|
||||
import protect.card_locker.importexport.MultiFormatExporter;
|
||||
import protect.card_locker.importexport.MultiFormatImporter;
|
||||
|
||||
class ImportExportTask extends AsyncTask<Void, Void, ImportExportResult>
|
||||
{
|
||||
public class ImportExportTask implements CompatCallable<ImportExportResult> {
|
||||
private static final String TAG = "Catima";
|
||||
|
||||
private Activity activity;
|
||||
@@ -35,9 +34,8 @@ class ImportExportTask extends AsyncTask<Void, Void, ImportExportResult>
|
||||
/**
|
||||
* Constructor which will setup a task for exporting to the given file
|
||||
*/
|
||||
ImportExportTask(Activity activity, DataFormat format, OutputStream output,char[] password,
|
||||
TaskCompleteListener listener)
|
||||
{
|
||||
ImportExportTask(Activity activity, DataFormat format, OutputStream output, char[] password,
|
||||
TaskCompleteListener listener) {
|
||||
super();
|
||||
this.activity = activity;
|
||||
this.doImport = false;
|
||||
@@ -51,8 +49,7 @@ class ImportExportTask extends AsyncTask<Void, Void, ImportExportResult>
|
||||
* Constructor which will setup a task for importing from the given InputStream.
|
||||
*/
|
||||
ImportExportTask(Activity activity, DataFormat format, InputStream input, char[] password,
|
||||
TaskCompleteListener listener)
|
||||
{
|
||||
TaskCompleteListener listener) {
|
||||
super();
|
||||
this.activity = activity;
|
||||
this.doImport = true;
|
||||
@@ -62,8 +59,7 @@ class ImportExportTask extends AsyncTask<Void, Void, ImportExportResult>
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
private ImportExportResult performImport(Context context, InputStream stream, DBHelper db, char[] password)
|
||||
{
|
||||
private ImportExportResult performImport(Context context, InputStream stream, DBHelper db, char[] password) {
|
||||
ImportExportResult importResult = MultiFormatImporter.importData(context, db, stream, format, password);
|
||||
|
||||
Log.i(TAG, "Import result: " + importResult.name());
|
||||
@@ -71,18 +67,14 @@ class ImportExportTask extends AsyncTask<Void, Void, ImportExportResult>
|
||||
return importResult;
|
||||
}
|
||||
|
||||
private ImportExportResult performExport(Context context, OutputStream stream, DBHelper db,char[] password)
|
||||
{
|
||||
private ImportExportResult performExport(Context context, OutputStream stream, DBHelper db, char[] password) {
|
||||
ImportExportResult result = ImportExportResult.GenericFailure;
|
||||
|
||||
try
|
||||
{
|
||||
try {
|
||||
OutputStreamWriter writer = new OutputStreamWriter(stream, StandardCharsets.UTF_8);
|
||||
result = MultiFormatExporter.exportData(context, db, stream, format,password);
|
||||
result = MultiFormatExporter.exportData(context, db, stream, format, password);
|
||||
writer.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Unable to export file", e);
|
||||
}
|
||||
|
||||
@@ -91,55 +83,55 @@ class ImportExportTask extends AsyncTask<Void, Void, ImportExportResult>
|
||||
return result;
|
||||
}
|
||||
|
||||
protected void onPreExecute()
|
||||
{
|
||||
public void onPreExecute() {
|
||||
progress = new ProgressDialog(activity);
|
||||
progress.setTitle(doImport ? R.string.importing : R.string.exporting);
|
||||
|
||||
progress.setOnDismissListener(new DialogInterface.OnDismissListener()
|
||||
{
|
||||
progress.setOnDismissListener(new DialogInterface.OnDismissListener() {
|
||||
@Override
|
||||
public void onDismiss(DialogInterface dialog)
|
||||
{
|
||||
ImportExportTask.this.cancel(true);
|
||||
public void onDismiss(DialogInterface dialog) {
|
||||
ImportExportTask.this.stop();
|
||||
}
|
||||
});
|
||||
|
||||
progress.show();
|
||||
}
|
||||
|
||||
protected ImportExportResult doInBackground(Void... nothing)
|
||||
{
|
||||
protected ImportExportResult doInBackground(Void... nothing) {
|
||||
final DBHelper db = new DBHelper(activity);
|
||||
ImportExportResult result;
|
||||
|
||||
if(doImport)
|
||||
{
|
||||
if (doImport) {
|
||||
result = performImport(activity.getApplicationContext(), inputStream, db, password);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = performExport(activity.getApplicationContext(), outputStream, db,password);
|
||||
} else {
|
||||
result = performExport(activity.getApplicationContext(), outputStream, db, password);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected void onPostExecute(ImportExportResult result)
|
||||
{
|
||||
listener.onTaskComplete(result, format);
|
||||
public void onPostExecute(Object castResult) {
|
||||
listener.onTaskComplete((ImportExportResult) castResult, format);
|
||||
|
||||
progress.dismiss();
|
||||
Log.i(TAG, (doImport ? "Import" : "Export") + " Complete");
|
||||
}
|
||||
|
||||
protected void onCancelled()
|
||||
{
|
||||
protected void onCancelled() {
|
||||
progress.dismiss();
|
||||
Log.i(TAG, (doImport ? "Import" : "Export") + " Cancelled");
|
||||
}
|
||||
interface TaskCompleteListener
|
||||
{
|
||||
|
||||
protected void stop() {
|
||||
// Whelp
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImportExportResult call() {
|
||||
return doInBackground();
|
||||
}
|
||||
|
||||
interface TaskCompleteListener {
|
||||
void onTaskComplete(ImportExportResult result, DataFormat format);
|
||||
}
|
||||
|
||||
|
||||
@@ -122,7 +122,7 @@ public class ImportURIHelper {
|
||||
headerColor = Integer.parseInt(unparsedHeaderColor);
|
||||
}
|
||||
|
||||
return new LoyaltyCard(-1, store, note, expiry, balance, balanceType, cardId, barcodeId, barcodeType, headerColor, 0, Utils.getUnixTime());
|
||||
return new LoyaltyCard(-1, store, note, expiry, balance, balanceType, cardId, barcodeId, barcodeType, headerColor, 0, Utils.getUnixTime(),100);
|
||||
} catch (NullPointerException | NumberFormatException | UnsupportedEncodingException ex) {
|
||||
throw new InvalidObjectException("Not a valid import URI");
|
||||
}
|
||||
|
||||
@@ -30,11 +30,12 @@ public class LoyaltyCard implements Parcelable {
|
||||
|
||||
public final int starStatus;
|
||||
public final long lastUsed;
|
||||
public int zoomLevel;
|
||||
|
||||
public LoyaltyCard(final int id, final String store, final String note, final Date expiry,
|
||||
final BigDecimal balance, final Currency balanceType, final String cardId,
|
||||
@Nullable final String barcodeId, @Nullable final CatimaBarcode barcodeType,
|
||||
@Nullable final Integer headerColor, final int starStatus, final long lastUsed)
|
||||
@Nullable final Integer headerColor, final int starStatus, final long lastUsed,final int zoomLevel)
|
||||
{
|
||||
this.id = id;
|
||||
this.store = store;
|
||||
@@ -48,6 +49,7 @@ public class LoyaltyCard implements Parcelable {
|
||||
this.headerColor = headerColor;
|
||||
this.starStatus = starStatus;
|
||||
this.lastUsed = lastUsed;
|
||||
this.zoomLevel = zoomLevel;
|
||||
}
|
||||
|
||||
protected LoyaltyCard(Parcel in) {
|
||||
@@ -66,6 +68,7 @@ public class LoyaltyCard implements Parcelable {
|
||||
headerColor = tmpHeaderColor != -1 ? tmpHeaderColor : null;
|
||||
starStatus = in.readInt();
|
||||
lastUsed = in.readLong();
|
||||
zoomLevel = in.readInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -82,6 +85,7 @@ public class LoyaltyCard implements Parcelable {
|
||||
parcel.writeInt(headerColor != null ? headerColor : -1);
|
||||
parcel.writeInt(starStatus);
|
||||
parcel.writeLong(lastUsed);
|
||||
parcel.writeInt(zoomLevel);
|
||||
}
|
||||
|
||||
public static LoyaltyCard toLoyaltyCard(Cursor cursor)
|
||||
@@ -95,6 +99,7 @@ public class LoyaltyCard implements Parcelable {
|
||||
String barcodeId = cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.BARCODE_ID));
|
||||
int starred = cursor.getInt(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.STAR_STATUS));
|
||||
long lastUsed = cursor.getLong(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.LAST_USED));
|
||||
int zoomLevel = cursor.getInt(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.ZOOM_LEVEL));
|
||||
|
||||
int barcodeTypeColumn = cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.BARCODE_TYPE);
|
||||
int balanceTypeColumn = cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.BALANCE_TYPE);
|
||||
@@ -125,7 +130,7 @@ public class LoyaltyCard implements Parcelable {
|
||||
headerColor = cursor.getInt(headerColorColumn);
|
||||
}
|
||||
|
||||
return new LoyaltyCard(id, store, note, expiry, balance, balanceType, cardId, barcodeId, barcodeType, headerColor, starred, lastUsed);
|
||||
return new LoyaltyCard(id, store, note, expiry, balance, balanceType, cardId, barcodeId, barcodeType, headerColor, starred, lastUsed,zoomLevel);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
package protect.card_locker;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.SparseBooleanArray;
|
||||
import android.util.TypedValue;
|
||||
import android.view.HapticFeedbackConstants;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
@@ -21,11 +22,13 @@ import java.math.BigDecimal;
|
||||
import java.text.DateFormat;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import androidx.core.graphics.BlendModeColorFilterCompat;
|
||||
import androidx.core.graphics.BlendModeCompat;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import protect.card_locker.preferences.Settings;
|
||||
|
||||
public class LoyaltyCardCursorAdapter extends BaseCursorAdapter<LoyaltyCardCursorAdapter.LoyaltyCardListItemViewHolder>
|
||||
{
|
||||
public class LoyaltyCardCursorAdapter extends BaseCursorAdapter<LoyaltyCardCursorAdapter.LoyaltyCardListItemViewHolder> {
|
||||
private int mCurrentSelectedIndex = -1;
|
||||
private Cursor mCursor;
|
||||
Settings mSettings;
|
||||
@@ -36,8 +39,7 @@ public class LoyaltyCardCursorAdapter extends BaseCursorAdapter<LoyaltyCardCurso
|
||||
private SparseBooleanArray mAnimationItemsIndex;
|
||||
private boolean mReverseAllAnimations = false;
|
||||
|
||||
public LoyaltyCardCursorAdapter(Context inputContext, Cursor inputCursor, CardAdapterListener inputListener)
|
||||
{
|
||||
public LoyaltyCardCursorAdapter(Context inputContext, Cursor inputCursor, CardAdapterListener inputListener) {
|
||||
super(inputCursor);
|
||||
setHasStableIds(true);
|
||||
mSettings = new Settings(inputContext);
|
||||
@@ -58,14 +60,12 @@ public class LoyaltyCardCursorAdapter extends BaseCursorAdapter<LoyaltyCardCurso
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoyaltyCardListItemViewHolder onCreateViewHolder(ViewGroup inputParent, int inputViewType)
|
||||
{
|
||||
public LoyaltyCardListItemViewHolder onCreateViewHolder(ViewGroup inputParent, int inputViewType) {
|
||||
View itemView = LayoutInflater.from(inputParent.getContext()).inflate(R.layout.loyalty_card_layout, inputParent, false);
|
||||
return new LoyaltyCardListItemViewHolder(itemView, mListener);
|
||||
}
|
||||
|
||||
public Cursor getCursor()
|
||||
{
|
||||
public Cursor getCursor() {
|
||||
return mCursor;
|
||||
}
|
||||
|
||||
@@ -73,8 +73,10 @@ public class LoyaltyCardCursorAdapter extends BaseCursorAdapter<LoyaltyCardCurso
|
||||
// Invisible until we want to show something more
|
||||
inputHolder.mDivider.setVisibility(View.GONE);
|
||||
|
||||
int size = mSettings.getFontSizeMax(mSettings.getSmallFont());
|
||||
|
||||
if (mDarkModeEnabled) {
|
||||
inputHolder.mStarIcon.setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_ATOP);
|
||||
inputHolder.mStarIcon.setColorFilter(BlendModeColorFilterCompat.createBlendModeColorFilterCompat(Color.WHITE, BlendModeCompat.SRC_ATOP));
|
||||
}
|
||||
|
||||
LoyaltyCard loyaltyCard = LoyaltyCard.toLoyaltyCard(inputCursor);
|
||||
@@ -84,49 +86,86 @@ public class LoyaltyCardCursorAdapter extends BaseCursorAdapter<LoyaltyCardCurso
|
||||
if (!loyaltyCard.note.isEmpty()) {
|
||||
inputHolder.mNoteField.setVisibility(View.VISIBLE);
|
||||
inputHolder.mNoteField.setText(loyaltyCard.note);
|
||||
inputHolder.mNoteField.setTextSize(mSettings.getFontSizeMax(mSettings.getSmallFont()));
|
||||
inputHolder.mNoteField.setTextSize(size);
|
||||
} else {
|
||||
inputHolder.mNoteField.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (!loyaltyCard.balance.equals(new BigDecimal("0"))) {
|
||||
int drawableSize = dpToPx((size*24)/14, mContext);
|
||||
inputHolder.mDivider.setVisibility(View.VISIBLE);
|
||||
inputHolder.mBalanceField.setVisibility(View.VISIBLE);
|
||||
Drawable balanceIcon = inputHolder.mBalanceField.getCompoundDrawables()[0];
|
||||
balanceIcon.setBounds(0,0,drawableSize,drawableSize);
|
||||
inputHolder.mBalanceField.setCompoundDrawablesRelative(balanceIcon, null, null, null);
|
||||
if (mDarkModeEnabled) {
|
||||
inputHolder.mBalanceField.getCompoundDrawables()[0].setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_ATOP);
|
||||
balanceIcon.setColorFilter(BlendModeColorFilterCompat.createBlendModeColorFilterCompat(Color.WHITE, BlendModeCompat.SRC_ATOP));
|
||||
}
|
||||
inputHolder.mBalanceField.setText(Utils.formatBalance(mContext, loyaltyCard.balance, loyaltyCard.balanceType));
|
||||
inputHolder.mBalanceField.setTextSize(mSettings.getFontSizeMax(mSettings.getSmallFont()));
|
||||
inputHolder.mBalanceField.setTextSize(size);
|
||||
} else {
|
||||
inputHolder.mBalanceField.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (loyaltyCard.expiry != null) {
|
||||
int drawableSize = dpToPx((size*24)/14, mContext);
|
||||
inputHolder.mDivider.setVisibility(View.VISIBLE);
|
||||
inputHolder.mExpiryField.setVisibility(View.VISIBLE);
|
||||
Drawable expiryIcon = inputHolder.mExpiryField.getCompoundDrawables()[0];
|
||||
expiryIcon.setBounds(0,0, drawableSize, drawableSize);
|
||||
inputHolder.mExpiryField.setCompoundDrawablesRelative(expiryIcon, null, null, null);
|
||||
if (Utils.hasExpired(loyaltyCard.expiry)) {
|
||||
expiryIcon.setColorFilter(Color.RED, PorterDuff.Mode.SRC_ATOP);
|
||||
expiryIcon.setColorFilter(BlendModeColorFilterCompat.createBlendModeColorFilterCompat(Color.RED, BlendModeCompat.SRC_ATOP));
|
||||
inputHolder.mExpiryField.setTextColor(Color.RED);
|
||||
} else if (mDarkModeEnabled) {
|
||||
expiryIcon.setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_ATOP);
|
||||
expiryIcon.setColorFilter(BlendModeColorFilterCompat.createBlendModeColorFilterCompat(Color.WHITE, BlendModeCompat.SRC_ATOP));
|
||||
}
|
||||
inputHolder.mExpiryField.setText(DateFormat.getDateInstance(DateFormat.LONG).format(loyaltyCard.expiry));
|
||||
inputHolder.mExpiryField.setTextSize(mSettings.getFontSizeMax(mSettings.getSmallFont()));
|
||||
inputHolder.mExpiryField.setTextSize(size);
|
||||
} else {
|
||||
inputHolder.mExpiryField.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
inputHolder.mStarIcon.setVisibility(loyaltyCard.starStatus != 0 ? View.VISIBLE : View.GONE);
|
||||
inputHolder.mCardIcon.setImageBitmap(Utils.generateIcon(mContext, loyaltyCard.store, loyaltyCard.headerColor).getLetterTile());
|
||||
int imageSize = dpToPx( (size*46)/14, mContext);
|
||||
inputHolder.mCardIcon.getLayoutParams().height = imageSize;
|
||||
inputHolder.mCardIcon.getLayoutParams().width = imageSize;
|
||||
inputHolder.mStarIcon.getLayoutParams().height = imageSize;
|
||||
inputHolder.mStarIcon.getLayoutParams().width = imageSize;
|
||||
inputHolder.mTickIcon.getLayoutParams().height = imageSize;
|
||||
inputHolder.mTickIcon.getLayoutParams().width = imageSize;
|
||||
|
||||
/* Changing Padding and Mragin of different views according to font size
|
||||
* Views Included:
|
||||
* a) InformationContainer padding
|
||||
* b) Store left padding
|
||||
* c) Divider Margin
|
||||
* d) note top margin
|
||||
* e) row margin
|
||||
* */
|
||||
int marginPaddingSize = dpToPx((size*16)/14, mContext );
|
||||
inputHolder.mInformationContainer.setPadding(marginPaddingSize, marginPaddingSize, marginPaddingSize, marginPaddingSize);
|
||||
inputHolder.mStoreField.setPadding(marginPaddingSize, 0, 0, 0);
|
||||
LinearLayout.LayoutParams lpDivider = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT );
|
||||
lpDivider.setMargins(0, marginPaddingSize, 0, marginPaddingSize);
|
||||
inputHolder.mDivider.setLayoutParams(lpDivider);
|
||||
LinearLayout.LayoutParams lpNoteField = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT );
|
||||
lpNoteField.setMargins(0, marginPaddingSize/2, 0, 0);
|
||||
inputHolder.mNoteField.setLayoutParams(lpNoteField);
|
||||
LinearLayout.LayoutParams lpRow = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT );
|
||||
lpRow.setMargins(marginPaddingSize/2, marginPaddingSize/2, marginPaddingSize/2, marginPaddingSize/2);
|
||||
inputHolder.mRow.setLayoutParams(lpRow);
|
||||
|
||||
inputHolder.itemView.setActivated(mSelectedItems.get(inputCursor.getPosition(), false));
|
||||
applyIconAnimation(inputHolder, inputCursor.getPosition());
|
||||
applyClickEvents(inputHolder, inputCursor.getPosition());
|
||||
}
|
||||
|
||||
private void applyClickEvents(LoyaltyCardListItemViewHolder inputHolder, final int inputPosition)
|
||||
{
|
||||
private void applyClickEvents(LoyaltyCardListItemViewHolder inputHolder, final int inputPosition) {
|
||||
inputHolder.mRow.setOnClickListener(inputView -> mListener.onRowClicked(inputPosition));
|
||||
inputHolder.mInformationContainer.setOnClickListener(inputView -> mListener.onRowClicked(inputPosition));
|
||||
|
||||
@@ -143,85 +182,68 @@ public class LoyaltyCardCursorAdapter extends BaseCursorAdapter<LoyaltyCardCurso
|
||||
});
|
||||
}
|
||||
|
||||
private void applyIconAnimation(LoyaltyCardListItemViewHolder inputHolder, int inputPosition)
|
||||
{
|
||||
if (mSelectedItems.get(inputPosition, false))
|
||||
{
|
||||
private void applyIconAnimation(LoyaltyCardListItemViewHolder inputHolder, int inputPosition) {
|
||||
if (mSelectedItems.get(inputPosition, false)) {
|
||||
inputHolder.mThumbnailFrontContainer.setVisibility(View.GONE);
|
||||
resetIconYAxis(inputHolder.mThumbnailBackContainer);
|
||||
inputHolder.mThumbnailBackContainer.setVisibility(View.VISIBLE);
|
||||
inputHolder.mThumbnailBackContainer.setAlpha(1);
|
||||
if (mCurrentSelectedIndex == inputPosition)
|
||||
{
|
||||
if (mCurrentSelectedIndex == inputPosition) {
|
||||
LoyaltyCardAnimator.flipView(mContext, inputHolder.mThumbnailBackContainer, inputHolder.mThumbnailFrontContainer, true);
|
||||
resetCurrentIndex();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
inputHolder.mThumbnailBackContainer.setVisibility(View.GONE);
|
||||
resetIconYAxis(inputHolder.mThumbnailFrontContainer);
|
||||
inputHolder.mThumbnailFrontContainer.setVisibility(View.VISIBLE);
|
||||
inputHolder.mThumbnailFrontContainer.setAlpha(1);
|
||||
if ((mReverseAllAnimations && mAnimationItemsIndex.get(inputPosition, false)) || mCurrentSelectedIndex == inputPosition)
|
||||
{
|
||||
if ((mReverseAllAnimations && mAnimationItemsIndex.get(inputPosition, false)) || mCurrentSelectedIndex == inputPosition) {
|
||||
LoyaltyCardAnimator.flipView(mContext, inputHolder.mThumbnailBackContainer, inputHolder.mThumbnailFrontContainer, false);
|
||||
resetCurrentIndex();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void resetIconYAxis(View inputView)
|
||||
{
|
||||
if (inputView.getRotationY() != 0)
|
||||
{
|
||||
private void resetIconYAxis(View inputView) {
|
||||
if (inputView.getRotationY() != 0) {
|
||||
inputView.setRotationY(0);
|
||||
}
|
||||
}
|
||||
|
||||
public void resetAnimationIndex()
|
||||
{
|
||||
public void resetAnimationIndex() {
|
||||
mReverseAllAnimations = false;
|
||||
mAnimationItemsIndex.clear();
|
||||
}
|
||||
|
||||
|
||||
public void toggleSelection(int inputPosition)
|
||||
{
|
||||
public void toggleSelection(int inputPosition) {
|
||||
mCurrentSelectedIndex = inputPosition;
|
||||
if (mSelectedItems.get(inputPosition, false))
|
||||
{
|
||||
if (mSelectedItems.get(inputPosition, false)) {
|
||||
mSelectedItems.delete(inputPosition);
|
||||
mAnimationItemsIndex.delete(inputPosition);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
mSelectedItems.put(inputPosition, true);
|
||||
mAnimationItemsIndex.put(inputPosition, true);
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void clearSelections()
|
||||
{
|
||||
public void clearSelections() {
|
||||
mReverseAllAnimations = true;
|
||||
mSelectedItems.clear();
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public int getSelectedItemCount()
|
||||
{
|
||||
public int getSelectedItemCount() {
|
||||
return mSelectedItems.size();
|
||||
}
|
||||
|
||||
public ArrayList<LoyaltyCard> getSelectedItems()
|
||||
{
|
||||
public ArrayList<LoyaltyCard> getSelectedItems() {
|
||||
|
||||
ArrayList<LoyaltyCard> result = new ArrayList<>();
|
||||
|
||||
int i;
|
||||
for(i = 0; i < mSelectedItems.size(); i++)
|
||||
{
|
||||
for (i = 0; i < mSelectedItems.size(); i++) {
|
||||
mCursor.moveToPosition(mSelectedItems.keyAt(i));
|
||||
result.add(LoyaltyCard.toLoyaltyCard(mCursor));
|
||||
}
|
||||
@@ -229,29 +251,26 @@ public class LoyaltyCardCursorAdapter extends BaseCursorAdapter<LoyaltyCardCurso
|
||||
return result;
|
||||
}
|
||||
|
||||
private void resetCurrentIndex()
|
||||
{
|
||||
private void resetCurrentIndex() {
|
||||
mCurrentSelectedIndex = -1;
|
||||
}
|
||||
|
||||
public interface CardAdapterListener
|
||||
{
|
||||
public interface CardAdapterListener {
|
||||
void onRowClicked(int inputPosition);
|
||||
|
||||
void onRowLongClicked(int inputPosition);
|
||||
}
|
||||
|
||||
public static class LoyaltyCardListItemViewHolder extends RecyclerView.ViewHolder
|
||||
{
|
||||
public static class LoyaltyCardListItemViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
public TextView mStoreField, mNoteField, mBalanceField, mExpiryField;
|
||||
public LinearLayout mInformationContainer;
|
||||
public ImageView mCardIcon, mStarIcon;
|
||||
public ImageView mCardIcon, mStarIcon, mTickIcon;
|
||||
public MaterialCardView mRow;
|
||||
public View mDivider;
|
||||
public RelativeLayout mThumbnailFrontContainer, mThumbnailBackContainer;
|
||||
|
||||
public LoyaltyCardListItemViewHolder(View inputView, CardAdapterListener inputListener)
|
||||
{
|
||||
public LoyaltyCardListItemViewHolder(View inputView, CardAdapterListener inputListener) {
|
||||
super(inputView);
|
||||
mRow = inputView.findViewById(R.id.row);
|
||||
mDivider = inputView.findViewById(R.id.info_divider);
|
||||
@@ -264,6 +283,7 @@ public class LoyaltyCardCursorAdapter extends BaseCursorAdapter<LoyaltyCardCurso
|
||||
mExpiryField = inputView.findViewById(R.id.expiry);
|
||||
mCardIcon = inputView.findViewById(R.id.thumbnail);
|
||||
mStarIcon = inputView.findViewById(R.id.star);
|
||||
mTickIcon = inputView.findViewById(R.id.selected_thumbnail);
|
||||
inputView.setOnLongClickListener(view -> {
|
||||
inputListener.onRowClicked(getAdapterPosition());
|
||||
inputView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
|
||||
@@ -271,4 +291,10 @@ public class LoyaltyCardCursorAdapter extends BaseCursorAdapter<LoyaltyCardCurso
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int dpToPx(int dp, Context mContext){
|
||||
Resources r = mContext.getResources();
|
||||
int px = (int)TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics());
|
||||
return px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,6 @@ import com.google.android.material.chip.ChipGroup;
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
import com.jaredrummler.android.colorpicker.ColorPickerDialog;
|
||||
import com.jaredrummler.android.colorpicker.ColorPickerDialogListener;
|
||||
|
||||
@@ -72,8 +71,9 @@ import androidx.core.content.FileProvider;
|
||||
import androidx.exifinterface.media.ExifInterface;
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
|
||||
public class LoyaltyCardEditActivity extends CatimaAppCompatActivity
|
||||
{
|
||||
import protect.card_locker.async.TaskHandler;
|
||||
|
||||
public class LoyaltyCardEditActivity extends CatimaAppCompatActivity {
|
||||
private static final String TAG = "Catima";
|
||||
|
||||
private final String STATE_TAB_INDEX = "savedTab";
|
||||
@@ -141,6 +141,8 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity
|
||||
|
||||
LoyaltyCard tempLoyaltyCard;
|
||||
|
||||
final private TaskHandler mTasks = new TaskHandler();
|
||||
|
||||
private static LoyaltyCard updateTempState(LoyaltyCard loyaltyCard, LoyaltyCardField fieldName, Object value) {
|
||||
return new LoyaltyCard(
|
||||
(int) (fieldName == LoyaltyCardField.id ? value : loyaltyCard.id),
|
||||
@@ -154,7 +156,7 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity
|
||||
(CatimaBarcode) (fieldName == LoyaltyCardField.barcodeType ? value : loyaltyCard.barcodeType),
|
||||
(Integer) (fieldName == LoyaltyCardField.headerColor ? value : loyaltyCard.headerColor),
|
||||
(int) (fieldName == LoyaltyCardField.starStatus ? value : loyaltyCard.starStatus),
|
||||
Utils.getUnixTime()
|
||||
Utils.getUnixTime(),100
|
||||
);
|
||||
}
|
||||
|
||||
@@ -164,8 +166,7 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity
|
||||
hasChanged = true;
|
||||
}
|
||||
|
||||
private void extractIntentFields(Intent intent)
|
||||
{
|
||||
private void extractIntentFields(Intent intent) {
|
||||
final Bundle b = intent.getExtras();
|
||||
loyaltyCardId = b != null ? b.getInt(BUNDLE_ID) : 0;
|
||||
updateLoyaltyCard = b != null && b.getBoolean(BUNDLE_UPDATE, false);
|
||||
@@ -205,8 +206,7 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
if(actionBar != null)
|
||||
{
|
||||
if (actionBar != null) {
|
||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
|
||||
@@ -416,7 +416,8 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity
|
||||
} else if (s.toString().equals(getString(R.string.setBarcodeId))) {
|
||||
if (!lastValue.toString().equals(getString(R.string.setBarcodeId))) {
|
||||
barcodeIdField.setText(lastValue);
|
||||
};
|
||||
}
|
||||
;
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(LoyaltyCardEditActivity.this);
|
||||
builder.setTitle(R.string.setBarcodeId);
|
||||
@@ -471,7 +472,8 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity
|
||||
if (!barcodeFormat.isSupported()) {
|
||||
Toast.makeText(LoyaltyCardEditActivity.this, getString(R.string.unsupportedBarcodeType), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
} catch (IllegalArgumentException e) {}
|
||||
} catch (IllegalArgumentException e) {
|
||||
}
|
||||
}
|
||||
|
||||
generateOrHideBarcode();
|
||||
@@ -510,8 +512,7 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewIntent(Intent intent)
|
||||
{
|
||||
public void onNewIntent(Intent intent) {
|
||||
super.onNewIntent(intent);
|
||||
|
||||
Log.i(TAG, "Received new intent");
|
||||
@@ -520,15 +521,14 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity
|
||||
|
||||
@SuppressLint("DefaultLocale")
|
||||
@Override
|
||||
public void onResume()
|
||||
{
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
Log.i(TAG, "To view card: " + loyaltyCardId);
|
||||
|
||||
onResuming = true;
|
||||
|
||||
if(tempLoyaltyCard == null) {
|
||||
if (tempLoyaltyCard == null) {
|
||||
if (updateLoyaltyCard) {
|
||||
tempLoyaltyCard = db.getLoyaltyCard(loyaltyCardId);
|
||||
if (tempLoyaltyCard == null) {
|
||||
@@ -551,7 +551,7 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity
|
||||
setTitle(R.string.addCardTitle);
|
||||
} else {
|
||||
// New card, use default values
|
||||
tempLoyaltyCard = new LoyaltyCard(-1, "", "", null, new BigDecimal("0"), null, "", null, null, null, 0, Utils.getUnixTime());
|
||||
tempLoyaltyCard = new LoyaltyCard(-1, "", "", null, new BigDecimal("0"), null, "", null, null, null, 0, Utils.getUnixTime(),100);
|
||||
setTitle(R.string.addCardTitle);
|
||||
}
|
||||
}
|
||||
@@ -564,8 +564,7 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity
|
||||
barcodeIdField.setText(tempLoyaltyCard.barcodeId != null ? tempLoyaltyCard.barcodeId : getString(R.string.sameAsCardId));
|
||||
barcodeTypeField.setText(tempLoyaltyCard.barcodeType != null ? tempLoyaltyCard.barcodeType.prettyName() : getString(R.string.noBarcode));
|
||||
|
||||
if(groupsChips.getChildCount() == 0)
|
||||
{
|
||||
if (groupsChips.getChildCount() == 0) {
|
||||
List<Group> existingGroups = db.getGroups();
|
||||
|
||||
List<Group> loyaltyCardGroups = db.getLoyaltyCardGroups(loyaltyCardId);
|
||||
@@ -604,18 +603,17 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity
|
||||
}
|
||||
|
||||
// Generate random header color
|
||||
if(tempLoyaltyCard.headerColor == null)
|
||||
{
|
||||
if (tempLoyaltyCard.headerColor == null) {
|
||||
// Select a random color to start out with.
|
||||
TypedArray colors = getResources().obtainTypedArray(R.array.letter_tile_colors);
|
||||
final int color = (int)(Math.random() * colors.length());
|
||||
final int color = (int) (Math.random() * colors.length());
|
||||
updateTempState(LoyaltyCardField.headerColor, colors.getColor(color, Color.BLACK));
|
||||
colors.recycle();
|
||||
}
|
||||
|
||||
// It can't be null because we set it in updateTempState but SpotBugs insists it can be
|
||||
// NP_NULL_ON_SOME_PATH: Possible null pointer dereference
|
||||
if(tempLoyaltyCard.headerColor != null) {
|
||||
if (tempLoyaltyCard.headerColor != null) {
|
||||
thumbnail.setOnClickListener(new ColorSelectListener());
|
||||
}
|
||||
|
||||
@@ -806,11 +804,9 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity
|
||||
startActivityForResult(i, type);
|
||||
}
|
||||
|
||||
class EditCardIdAndBarcode implements View.OnClickListener
|
||||
{
|
||||
class EditCardIdAndBarcode implements View.OnClickListener {
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
public void onClick(View v) {
|
||||
Intent i = new Intent(getApplicationContext(), ScanActivity.class);
|
||||
final Bundle b = new Bundle();
|
||||
b.putString(LoyaltyCardEditActivity.BUNDLE_CARDID, cardIdFieldView.getText().toString());
|
||||
@@ -819,11 +815,9 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity
|
||||
}
|
||||
}
|
||||
|
||||
class ChooseCardImage implements View.OnClickListener
|
||||
{
|
||||
class ChooseCardImage implements View.OnClickListener {
|
||||
@Override
|
||||
public void onClick(View v) throws NoSuchElementException
|
||||
{
|
||||
public void onClick(View v) throws NoSuchElementException {
|
||||
ImageView targetView = v.getId() == ID_IMAGE_FRONT ? cardImageFront : cardImageBack;
|
||||
|
||||
LinkedHashMap<String, Callable<Void>> cardOptions = new LinkedHashMap<>();
|
||||
@@ -870,11 +864,9 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity
|
||||
}
|
||||
}
|
||||
|
||||
class ColorSelectListener implements View.OnClickListener
|
||||
{
|
||||
class ColorSelectListener implements View.OnClickListener {
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
public void onClick(View v) {
|
||||
ColorPickerDialog.Builder dialogBuilder = ColorPickerDialog.newBuilder();
|
||||
|
||||
if (tempLoyaltyCard.headerColor != null) {
|
||||
@@ -882,19 +874,16 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity
|
||||
}
|
||||
|
||||
ColorPickerDialog dialog = dialogBuilder.create();
|
||||
dialog.setColorPickerDialogListener(new ColorPickerDialogListener()
|
||||
{
|
||||
dialog.setColorPickerDialogListener(new ColorPickerDialogListener() {
|
||||
@Override
|
||||
public void onColorSelected(int dialogId, int color)
|
||||
{
|
||||
public void onColorSelected(int dialogId, int color) {
|
||||
updateTempState(LoyaltyCardField.headerColor, color);
|
||||
|
||||
generateIcon(storeFieldEdit.getText().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDialogDismissed(int dialogId)
|
||||
{
|
||||
public void onDialogDismissed(int dialogId) {
|
||||
// Nothing to do, no change made
|
||||
}
|
||||
});
|
||||
@@ -955,20 +944,17 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity
|
||||
return;
|
||||
}
|
||||
|
||||
if(tempLoyaltyCard.store.isEmpty())
|
||||
{
|
||||
if (tempLoyaltyCard.store.isEmpty()) {
|
||||
Snackbar.make(storeFieldEdit, R.string.noStoreError, Snackbar.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if(tempLoyaltyCard.cardId.isEmpty())
|
||||
{
|
||||
if (tempLoyaltyCard.cardId.isEmpty()) {
|
||||
Snackbar.make(cardIdFieldView, R.string.noCardIdError, Snackbar.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if(!validBalance)
|
||||
{
|
||||
if (!validBalance) {
|
||||
Snackbar.make(balanceField, getString(R.string.parsingBalanceFailed, balanceField.getText().toString()), Snackbar.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
@@ -980,8 +966,7 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity
|
||||
selectedGroups.add((Group) chip.getTag());
|
||||
}
|
||||
|
||||
if(updateLoyaltyCard)
|
||||
{ //update of "starStatus" not necessary, since it cannot be changed in this activity (only in ViewActivity)
|
||||
if (updateLoyaltyCard) { //update of "starStatus" not necessary, since it cannot be changed in this activity (only in ViewActivity)
|
||||
db.updateLoyaltyCard(loyaltyCardId, tempLoyaltyCard.store, tempLoyaltyCard.note, tempLoyaltyCard.expiry, tempLoyaltyCard.balance, tempLoyaltyCard.balanceType, tempLoyaltyCard.cardId, tempLoyaltyCard.barcodeId, tempLoyaltyCard.barcodeType, tempLoyaltyCard.headerColor);
|
||||
try {
|
||||
Utils.saveCardImage(this, (Bitmap) cardImageFront.getTag(), loyaltyCardId, true);
|
||||
@@ -990,9 +975,7 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity
|
||||
e.printStackTrace();
|
||||
}
|
||||
Log.i(TAG, "Updated " + loyaltyCardId + " to " + cardId);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
loyaltyCardId = (int) db.insertLoyaltyCard(tempLoyaltyCard.store, tempLoyaltyCard.note, tempLoyaltyCard.expiry, tempLoyaltyCard.balance, tempLoyaltyCard.balanceType, tempLoyaltyCard.cardId, tempLoyaltyCard.barcodeId, tempLoyaltyCard.barcodeType, tempLoyaltyCard.headerColor, 0, tempLoyaltyCard.lastUsed);
|
||||
try {
|
||||
Utils.saveCardImage(this, (Bitmap) cardImageFront.getTag(), loyaltyCardId, true);
|
||||
@@ -1008,14 +991,10 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu)
|
||||
{
|
||||
if(updateLoyaltyCard)
|
||||
{
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
if (updateLoyaltyCard) {
|
||||
getMenuInflater().inflate(R.menu.card_update_menu, menu);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
getMenuInflater().inflate(R.menu.card_add_menu, menu);
|
||||
}
|
||||
|
||||
@@ -1023,12 +1002,10 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item)
|
||||
{
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
int id = item.getItemId();
|
||||
|
||||
switch(id)
|
||||
{
|
||||
switch (id) {
|
||||
case android.R.id.home:
|
||||
askBeforeQuitIfChanged();
|
||||
break;
|
||||
@@ -1059,8 +1036,7 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent intent)
|
||||
{
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
|
||||
super.onActivityResult(requestCode, resultCode, intent);
|
||||
|
||||
if (resultCode == RESULT_OK) {
|
||||
@@ -1143,6 +1119,8 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity
|
||||
}
|
||||
|
||||
private void generateBarcode(String cardIdString, CatimaBarcode barcodeFormat) {
|
||||
mTasks.flushTaskList(TaskHandler.TYPE.BARCODE, true, false, false);
|
||||
|
||||
if (barcodeImage.getHeight() == 0) {
|
||||
Log.d(TAG, "ImageView size is not known known at start, waiting for load");
|
||||
// The size of the ImageView is not yet available as it has not
|
||||
@@ -1154,12 +1132,14 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity
|
||||
barcodeImage.getViewTreeObserver().removeOnGlobalLayoutListener(this);
|
||||
|
||||
Log.d(TAG, "ImageView size now known");
|
||||
new BarcodeImageWriterTask(getApplicationContext(), barcodeImage, cardIdString, barcodeFormat, null, false, warnOnInvalidBarcodeType).execute();
|
||||
BarcodeImageWriterTask barcodeWriter = new BarcodeImageWriterTask(getApplicationContext(), barcodeImage, cardIdString, barcodeFormat, null, false, warnOnInvalidBarcodeType);
|
||||
mTasks.executeTask(TaskHandler.TYPE.BARCODE, barcodeWriter);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Log.d(TAG, "ImageView size known known, creating barcode");
|
||||
new BarcodeImageWriterTask(getApplicationContext(), barcodeImage, cardIdString, barcodeFormat, null, false, warnOnInvalidBarcodeType).execute();
|
||||
BarcodeImageWriterTask barcodeWriter = new BarcodeImageWriterTask(getApplicationContext(), barcodeImage, cardIdString, barcodeFormat, null, false, warnOnInvalidBarcodeType);
|
||||
mTasks.executeTask(TaskHandler.TYPE.BARCODE, barcodeWriter);
|
||||
}
|
||||
|
||||
showBarcode();
|
||||
|
||||
@@ -30,7 +30,6 @@ import android.widget.Toast;
|
||||
import com.google.android.material.appbar.AppBarLayout;
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior;
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigDecimal;
|
||||
@@ -48,10 +47,11 @@ import androidx.constraintlayout.widget.Guideline;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.graphics.drawable.DrawableCompat;
|
||||
import androidx.core.widget.TextViewCompat;
|
||||
|
||||
import protect.card_locker.async.TaskHandler;
|
||||
import protect.card_locker.preferences.Settings;
|
||||
|
||||
public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements GestureDetector.OnGestureListener
|
||||
{
|
||||
public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements GestureDetector.OnGestureListener {
|
||||
private static final String TAG = "Catima";
|
||||
|
||||
private GestureDetector mGestureDetector;
|
||||
@@ -102,6 +102,8 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
|
||||
static final String STATE_IMAGEINDEX = "imageIndex";
|
||||
static final String STATE_FULLSCREEN = "isFullscreen";
|
||||
|
||||
final private TaskHandler mTasks = new TaskHandler();
|
||||
|
||||
@Override
|
||||
public boolean onDown(MotionEvent e) {
|
||||
return true;
|
||||
@@ -182,8 +184,7 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
|
||||
IMAGE_BACK
|
||||
}
|
||||
|
||||
private void extractIntentFields(Intent intent)
|
||||
{
|
||||
private void extractIntentFields(Intent intent) {
|
||||
final Bundle b = intent.getExtras();
|
||||
loyaltyCardId = b != null ? b.getInt("id") : 0;
|
||||
Log.d(TAG, "View activity: id=" + loyaltyCardId);
|
||||
@@ -198,17 +199,13 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
|
||||
return wrappedIcon;
|
||||
}
|
||||
|
||||
private Drawable getIcon(int icon, boolean dark)
|
||||
{
|
||||
private Drawable getIcon(int icon, boolean dark) {
|
||||
Drawable unwrappedIcon = AppCompatResources.getDrawable(this, icon);
|
||||
assert unwrappedIcon != null;
|
||||
Drawable wrappedIcon = DrawableCompat.wrap(unwrappedIcon);
|
||||
if(dark)
|
||||
{
|
||||
if (dark) {
|
||||
DrawableCompat.setTint(wrappedIcon, Color.BLACK);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
DrawableCompat.setTintList(wrappedIcon, null);
|
||||
}
|
||||
|
||||
@@ -216,8 +213,7 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
@@ -251,9 +247,7 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
|
||||
appBarLayout = findViewById(R.id.app_bar_layout);
|
||||
|
||||
centerGuideline = findViewById(R.id.centerGuideline);
|
||||
centerGuideline.setGuidelinePercent(0.5f);
|
||||
barcodeScaler = findViewById(R.id.barcodeScaler);
|
||||
barcodeScaler.setProgress(100);
|
||||
maximizeButton.setBackgroundColor(getThemeColor());
|
||||
minimizeButton.setBackgroundColor(getThemeColor());
|
||||
bottomSheetButton.setBackgroundColor(getThemeColor());
|
||||
@@ -265,13 +259,18 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
|
||||
float scale = (float) progress / (float) barcodeScaler.getMax();
|
||||
Log.d(TAG, "Scaling to " + scale);
|
||||
|
||||
if (imageTypes.get(mainImageIndex) == ImageType.BARCODE) {
|
||||
redrawBarcodeAfterResize();
|
||||
if(isFullscreen){
|
||||
loyaltyCard.zoomLevel = progress;
|
||||
db.updateLoyaltyCardZoomLevel(loyaltyCardId, loyaltyCard.zoomLevel);
|
||||
}
|
||||
if(loyaltyCard!=null && format!=null && format.isSquare())
|
||||
|
||||
if (format != null && format.isSquare()) {
|
||||
centerGuideline.setGuidelinePercent(0.75f * scale);
|
||||
else
|
||||
} else {
|
||||
centerGuideline.setGuidelinePercent(0.5f * scale);
|
||||
}
|
||||
|
||||
drawMainImage(mainImageIndex, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -324,7 +323,8 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSlide(@NonNull View bottomSheet, float slideOffset) { }
|
||||
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
|
||||
}
|
||||
});
|
||||
|
||||
bottomSheetButton.setOnClickListener(v -> {
|
||||
@@ -360,8 +360,7 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewIntent(Intent intent)
|
||||
{
|
||||
public void onNewIntent(Intent intent) {
|
||||
super.onNewIntent(intent);
|
||||
|
||||
Log.i(TAG, "Received new intent");
|
||||
@@ -377,8 +376,7 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
|
||||
|
||||
|
||||
@Override
|
||||
public void onResume()
|
||||
{
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
Log.i(TAG, "To view card: " + loyaltyCardId);
|
||||
@@ -387,12 +385,10 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
|
||||
// '1' is the brightest. We attempt to maximize the brightness
|
||||
// to help barcode readers scan the barcode.
|
||||
Window window = getWindow();
|
||||
if(window != null)
|
||||
{
|
||||
if (window != null) {
|
||||
WindowManager.LayoutParams attributes = window.getAttributes();
|
||||
|
||||
if (settings.useMaxBrightnessDisplayingBarcode())
|
||||
{
|
||||
if (settings.useMaxBrightnessDisplayingBarcode()) {
|
||||
attributes.screenBrightness = 1F;
|
||||
}
|
||||
|
||||
@@ -401,7 +397,7 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
|
||||
}
|
||||
|
||||
if (settings.getDisableLockscreenWhileViewingCard()) {
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD|
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
|
||||
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
|
||||
}
|
||||
|
||||
@@ -409,8 +405,7 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
|
||||
}
|
||||
|
||||
loyaltyCard = db.getLoyaltyCard(loyaltyCardId);
|
||||
if(loyaltyCard == null)
|
||||
{
|
||||
if (loyaltyCard == null) {
|
||||
Log.w(TAG, "Could not lookup loyalty card " + loyaltyCardId);
|
||||
Toast.makeText(this, R.string.noCardExistsError, Toast.LENGTH_LONG).show();
|
||||
finish();
|
||||
@@ -420,12 +415,6 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
|
||||
setupOrientation();
|
||||
|
||||
format = loyaltyCard.barcodeType;
|
||||
if(format != null && format.isSquare()){
|
||||
centerGuideline.setGuidelinePercent(0.75f);
|
||||
}
|
||||
else{
|
||||
centerGuideline.setGuidelinePercent(0.5f);
|
||||
}
|
||||
cardIdString = loyaltyCard.cardId;
|
||||
barcodeIdString = loyaltyCard.barcodeId;
|
||||
|
||||
@@ -434,20 +423,17 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
|
||||
settings.getFontSizeMin(settings.getLargeFont()), settings.getFontSizeMax(settings.getLargeFont()),
|
||||
1, TypedValue.COMPLEX_UNIT_SP);
|
||||
|
||||
if(loyaltyCard.note.length() > 0)
|
||||
{
|
||||
if (loyaltyCard.note.length() > 0) {
|
||||
noteView.setVisibility(View.VISIBLE);
|
||||
noteView.setText(loyaltyCard.note);
|
||||
noteView.setTextSize(settings.getFontSizeMax(settings.getMediumFont()));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
noteView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
List<Group> loyaltyCardGroups = db.getLoyaltyCardGroups(loyaltyCardId);
|
||||
|
||||
if(loyaltyCardGroups.size() > 0) {
|
||||
if (loyaltyCardGroups.size() > 0) {
|
||||
List<String> groupNames = new ArrayList<>();
|
||||
for (Group group : loyaltyCardGroups) {
|
||||
groupNames.add(group._id);
|
||||
@@ -456,35 +442,29 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
|
||||
groupsView.setVisibility(View.VISIBLE);
|
||||
groupsView.setText(getString(R.string.groupsList, TextUtils.join(", ", groupNames)));
|
||||
groupsView.setTextSize(settings.getFontSizeMax(settings.getMediumFont()));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
groupsView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if(!loyaltyCard.balance.equals(new BigDecimal(0))) {
|
||||
if (!loyaltyCard.balance.equals(new BigDecimal(0))) {
|
||||
balanceView.setVisibility(View.VISIBLE);
|
||||
balanceView.setText(getString(R.string.balanceSentence, Utils.formatBalance(this, loyaltyCard.balance, loyaltyCard.balanceType)));
|
||||
balanceView.setTextSize(settings.getFontSizeMax(settings.getMediumFont()));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
balanceView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if(loyaltyCard.expiry != null) {
|
||||
if (loyaltyCard.expiry != null) {
|
||||
expiryView.setVisibility(View.VISIBLE);
|
||||
|
||||
int expiryString = R.string.expiryStateSentence;
|
||||
if(Utils.hasExpired(loyaltyCard.expiry)) {
|
||||
if (Utils.hasExpired(loyaltyCard.expiry)) {
|
||||
expiryString = R.string.expiryStateSentenceExpired;
|
||||
expiryView.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.alert));
|
||||
}
|
||||
expiryView.setText(getString(expiryString, DateFormat.getDateInstance(DateFormat.LONG).format(loyaltyCard.expiry)));
|
||||
expiryView.setTextSize(settings.getFontSizeMax(settings.getMediumFont()));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
expiryView.setVisibility(View.GONE);
|
||||
}
|
||||
expiryView.setTag(loyaltyCard.expiry);
|
||||
@@ -503,12 +483,9 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
|
||||
TypedValue.COMPLEX_UNIT_DIP);
|
||||
|
||||
int backgroundHeaderColor;
|
||||
if(loyaltyCard.headerColor != null)
|
||||
{
|
||||
if (loyaltyCard.headerColor != null) {
|
||||
backgroundHeaderColor = loyaltyCard.headerColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
backgroundHeaderColor = LetterBitmap.getDefaultColor(this, loyaltyCard.store);
|
||||
}
|
||||
|
||||
@@ -516,12 +493,9 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
|
||||
appBarLayout.setBackgroundColor(backgroundHeaderColor);
|
||||
|
||||
int textColor;
|
||||
if(Utils.needsDarkForeground(backgroundHeaderColor))
|
||||
{
|
||||
if (Utils.needsDarkForeground(backgroundHeaderColor)) {
|
||||
textColor = Color.BLACK;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
textColor = Color.WHITE;
|
||||
}
|
||||
storeName.setTextColor(textColor);
|
||||
@@ -530,14 +504,12 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
|
||||
// If the background is very bright, we should use dark icons
|
||||
backgroundNeedsDarkIcons = Utils.needsDarkForeground(backgroundHeaderColor);
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
if(actionBar != null)
|
||||
{
|
||||
if (actionBar != null) {
|
||||
actionBar.setHomeAsUpIndicator(getIcon(R.drawable.ic_arrow_back_white, backgroundNeedsDarkIcons));
|
||||
}
|
||||
|
||||
// Make notification area light if dark icons are needed
|
||||
if(Build.VERSION.SDK_INT >= 23)
|
||||
{
|
||||
if (Build.VERSION.SDK_INT >= 23) {
|
||||
window.getDecorView().setSystemUiVisibility(backgroundNeedsDarkIcons ? View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR : 0);
|
||||
}
|
||||
window.setStatusBarColor(Color.TRANSPARENT);
|
||||
@@ -594,8 +566,7 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (isFullscreen)
|
||||
{
|
||||
if (isFullscreen) {
|
||||
setFullscreen(false);
|
||||
return;
|
||||
}
|
||||
@@ -604,16 +575,14 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu)
|
||||
{
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.card_view_menu, menu);
|
||||
|
||||
// Always calculate lockscreen icon, it may need a black color
|
||||
boolean lockBarcodeScreenOrientation = settings.getLockBarcodeScreenOrientation();
|
||||
MenuItem item = menu.findItem(R.id.action_lock_unlock);
|
||||
setOrientatonLock(item, lockBarcodeScreenOrientation);
|
||||
if(lockBarcodeScreenOrientation)
|
||||
{
|
||||
if (lockBarcodeScreenOrientation) {
|
||||
item.setVisible(false);
|
||||
}
|
||||
|
||||
@@ -632,8 +601,7 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
|
||||
if (starred) {
|
||||
menu.findItem(R.id.action_star_unstar).setIcon(getIcon(R.drawable.ic_starred_white, backgroundNeedsDarkIcons));
|
||||
menu.findItem(R.id.action_star_unstar).setTitle(R.string.unstar);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
menu.findItem(R.id.action_star_unstar).setIcon(getIcon(R.drawable.ic_unstarred_white, backgroundNeedsDarkIcons));
|
||||
menu.findItem(R.id.action_star_unstar).setTitle(R.string.star);
|
||||
}
|
||||
@@ -641,12 +609,10 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item)
|
||||
{
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
int id = item.getItemId();
|
||||
|
||||
switch(id)
|
||||
{
|
||||
switch (id) {
|
||||
case android.R.id.home:
|
||||
finish();
|
||||
break;
|
||||
@@ -661,12 +627,9 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
|
||||
return true;
|
||||
|
||||
case R.id.action_lock_unlock:
|
||||
if(rotationEnabled)
|
||||
{
|
||||
if (rotationEnabled) {
|
||||
setOrientatonLock(item, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
setOrientatonLock(item, false);
|
||||
}
|
||||
rotationEnabled = !rotationEnabled;
|
||||
@@ -682,8 +645,7 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private void setupOrientation()
|
||||
{
|
||||
private void setupOrientation() {
|
||||
Toolbar portraitToolbar = findViewById(R.id.toolbar);
|
||||
Toolbar landscapeToolbar = findViewById(R.id.toolbar_landscape);
|
||||
|
||||
@@ -711,51 +673,44 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
|
||||
}
|
||||
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
if(actionBar != null)
|
||||
{
|
||||
if (actionBar != null) {
|
||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void setOrientatonLock(MenuItem item, boolean lock)
|
||||
{
|
||||
if(lock)
|
||||
{
|
||||
private void setOrientatonLock(MenuItem item, boolean lock) {
|
||||
if (lock) {
|
||||
|
||||
item.setIcon(getIcon(R.drawable.ic_lock_outline_white_24dp, backgroundNeedsDarkIcons));
|
||||
item.setTitle(R.string.unlockScreen);
|
||||
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
item.setIcon(getIcon(R.drawable.ic_lock_open_white_24dp, backgroundNeedsDarkIcons));
|
||||
item.setTitle(R.string.lockScreen);
|
||||
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
|
||||
}
|
||||
}
|
||||
|
||||
private void makeBottomSheetVisibleIfUseful()
|
||||
{
|
||||
private void makeBottomSheetVisibleIfUseful() {
|
||||
if (noteView.getVisibility() == View.VISIBLE || groupsView.getVisibility() == View.VISIBLE || balanceView.getVisibility() == View.VISIBLE || expiryView.getVisibility() == View.VISIBLE) {
|
||||
bottomSheet.setVisibility(View.VISIBLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
bottomSheet.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private void drawBarcode() {
|
||||
mTasks.flushTaskList(TaskHandler.TYPE.BARCODE, true, false, false);
|
||||
if (format != null) {
|
||||
new BarcodeImageWriterTask(
|
||||
BarcodeImageWriterTask barcodeWriter = new BarcodeImageWriterTask(
|
||||
getApplicationContext(),
|
||||
mainImage,
|
||||
barcodeIdString != null ? barcodeIdString : cardIdString,
|
||||
format,
|
||||
null,
|
||||
false,
|
||||
null)
|
||||
.execute();
|
||||
null);
|
||||
mTasks.executeTask(TaskHandler.TYPE.BARCODE, barcodeWriter);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -771,7 +726,7 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
|
||||
drawBarcode();
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private void drawMainImage(int index, boolean waitForResize) {
|
||||
@@ -831,6 +786,7 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
|
||||
* by machines which offer no space to insert the complete device.
|
||||
*/
|
||||
private void setFullscreen(boolean enabled) {
|
||||
isFullscreen = enabled;
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
|
||||
if (enabled && !imageTypes.isEmpty()) {
|
||||
@@ -838,14 +794,15 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
|
||||
|
||||
drawMainImage(mainImageIndex, true);
|
||||
|
||||
barcodeScaler.setProgress(loyaltyCard.zoomLevel);
|
||||
|
||||
// Hide maximize and show minimize button and scaler
|
||||
maximizeButton.setVisibility(View.GONE);
|
||||
minimizeButton.setVisibility(View.VISIBLE);
|
||||
barcodeScaler.setVisibility(View.VISIBLE);
|
||||
|
||||
// Hide actionbar
|
||||
if(actionBar != null)
|
||||
{
|
||||
if (actionBar != null) {
|
||||
actionBar.hide();
|
||||
}
|
||||
|
||||
@@ -870,9 +827,7 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
|
||||
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
|
||||
| View.SYSTEM_UI_FLAG_FULLSCREEN
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Log.d(TAG, "Move out of fullscreen");
|
||||
|
||||
// Reset center guideline
|
||||
@@ -887,8 +842,7 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
|
||||
barcodeScaler.setVisibility(View.GONE);
|
||||
|
||||
// Show actionbar
|
||||
if(actionBar != null)
|
||||
{
|
||||
if (actionBar != null) {
|
||||
actionBar.show();
|
||||
}
|
||||
|
||||
@@ -912,6 +866,6 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
|
||||
);
|
||||
}
|
||||
|
||||
isFullscreen = enabled;
|
||||
Log.d("setFullScreen","Is full screen enabled? "+enabled+" Zoom Level = "+barcodeScaler.getProgress());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Configuration;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.database.CursorIndexOutOfBoundsException;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.GestureDetector;
|
||||
@@ -737,7 +737,21 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard
|
||||
{
|
||||
Cursor selected = mAdapter.getCursor();
|
||||
selected.moveToPosition(inputPosition);
|
||||
LoyaltyCard loyaltyCard = LoyaltyCard.toLoyaltyCard(selected);
|
||||
// FIXME
|
||||
//
|
||||
// There is a really nasty edge case that can happen when someone taps a card but right
|
||||
// after it swipes (very small window, hard to reproduce). The cursor gets replaced and
|
||||
// may not have a card at the ID number that is returned from onRowClicked.
|
||||
//
|
||||
// The proper fix, obviously, would involve makes sure an onFling can't happen while a
|
||||
// click is being processed. Sadly, I have not yet found a way to make that possible.
|
||||
LoyaltyCard loyaltyCard;
|
||||
try {
|
||||
loyaltyCard = LoyaltyCard.toLoyaltyCard(selected);
|
||||
} catch (CursorIndexOutOfBoundsException e) {
|
||||
Log.w(TAG, "Prevented crash from tap + swipe on ID " + inputPosition + ": " + e);
|
||||
return;
|
||||
}
|
||||
|
||||
Intent i = new Intent(this, LoyaltyCardViewActivity.class);
|
||||
i.setAction("");
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package protect.card_locker.async;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public interface CompatCallable<T> extends Callable<T> {
|
||||
void onPostExecute(Object result);
|
||||
void onPreExecute();
|
||||
}
|
||||
174
app/src/main/java/protect/card_locker/async/TaskHandler.java
Normal file
174
app/src/main/java/protect/card_locker/async/TaskHandler.java
Normal file
@@ -0,0 +1,174 @@
|
||||
package protect.card_locker.async;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* AsyncTask has been deprecated so this provides very rudimentary compatibility without
|
||||
* needing to redo too many Parts.
|
||||
*
|
||||
* However this is a much, much more cooperative Behaviour than before so
|
||||
* the callers need to ensure we do NOT rely on forced cancellation and feed less into the
|
||||
* ThreadPools so we don't OOM/Overload the Users device
|
||||
*
|
||||
* This assumes single-threaded callers.
|
||||
*/
|
||||
public class TaskHandler {
|
||||
|
||||
public enum TYPE {
|
||||
BARCODE,
|
||||
IMPORT,
|
||||
EXPORT
|
||||
}
|
||||
|
||||
HashMap<TYPE, ThreadPoolExecutor> executors = generateExecutors();
|
||||
|
||||
final private HashMap<TYPE, LinkedList<Future<?>>> taskList = new HashMap<>();
|
||||
|
||||
private final Handler uiHandler = new Handler(Looper.getMainLooper());
|
||||
|
||||
private HashMap<TYPE, ThreadPoolExecutor> generateExecutors() {
|
||||
HashMap<TYPE, ThreadPoolExecutor> initExecutors = new HashMap<>();
|
||||
for (TYPE type : TYPE.values()) {
|
||||
replaceExecutor(initExecutors, type, false, false);
|
||||
}
|
||||
return initExecutors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces (or initializes) an Executor with a clean (new) one
|
||||
* @param executors Map Reference
|
||||
* @param type Which Queue
|
||||
* @param flushOld attempt shutdown
|
||||
* @param waitOnOld wait for Termination
|
||||
*/
|
||||
private void replaceExecutor(HashMap<TYPE, ThreadPoolExecutor> executors, TYPE type, Boolean flushOld, Boolean waitOnOld) {
|
||||
ThreadPoolExecutor oldExecutor = executors.get(type);
|
||||
if (oldExecutor != null) {
|
||||
if (flushOld) {
|
||||
oldExecutor.shutdownNow();
|
||||
}
|
||||
if (waitOnOld) {
|
||||
try {
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
oldExecutor.awaitTermination(5, TimeUnit.SECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
executors.put(type, (ThreadPoolExecutor) Executors.newCachedThreadPool());
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue a Pseudo-AsyncTask for execution
|
||||
*
|
||||
* @param type Queue
|
||||
* @param callable PseudoAsyncTask
|
||||
*/
|
||||
public void executeTask(TYPE type, CompatCallable<?> callable) {
|
||||
Runnable runner = () -> {
|
||||
try {
|
||||
// Run on the UI Thread
|
||||
uiHandler.post(callable::onPreExecute);
|
||||
|
||||
// Background
|
||||
final Object result = callable.call();
|
||||
|
||||
// Post results on UI Thread so we can show them
|
||||
uiHandler.post(() -> {
|
||||
callable.onPostExecute(result);
|
||||
});
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
};
|
||||
|
||||
LinkedList<Future<?>> list = taskList.get(type);
|
||||
|
||||
if (list == null) {
|
||||
list = new LinkedList<>();
|
||||
}
|
||||
|
||||
ThreadPoolExecutor executor = executors.get(type);
|
||||
|
||||
if (executor != null) {
|
||||
Future<?> task = executor.submit(runner);
|
||||
// Test Queue Cancellation:
|
||||
// task.cancel(true);
|
||||
list.push(task);
|
||||
taskList.put(type, list);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This will attempt to cancel a currently running list of Tasks
|
||||
* Useful to ignore scheduled tasks - but not able to hard-stop tasks that are running
|
||||
*
|
||||
* @param type Which Queue to target
|
||||
* @param forceCancel attempt to close the Queue and force-replace it after
|
||||
* @param waitForFinish wait and return after the old executor finished. Times out after 5s
|
||||
* @param waitForCurrentlyRunning wait before cancelling tasks. Useful for tests.
|
||||
*/
|
||||
public void flushTaskList(TYPE type, Boolean forceCancel, Boolean waitForFinish, Boolean waitForCurrentlyRunning) {
|
||||
// Only used for Testing
|
||||
if (waitForCurrentlyRunning) {
|
||||
ThreadPoolExecutor oldExecutor = executors.get(type);
|
||||
|
||||
if (oldExecutor != null) {
|
||||
try {
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
oldExecutor.awaitTermination(5, TimeUnit.SECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Attempt to cancel known Tasks and clean the List
|
||||
LinkedList<Future<?>> tasks = taskList.get(type);
|
||||
if (tasks != null) {
|
||||
for (Future<?> task : tasks) {
|
||||
if (!task.isDone() || !task.isCancelled()) {
|
||||
// Interrupt any Task we can
|
||||
task.cancel(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
tasks = new LinkedList<>();
|
||||
taskList.put(type, tasks);
|
||||
|
||||
if (forceCancel || waitForFinish) {
|
||||
ThreadPoolExecutor oldExecutor = executors.get(type);
|
||||
|
||||
if (oldExecutor != null) {
|
||||
if (forceCancel) {
|
||||
if (waitForFinish) {
|
||||
try {
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
oldExecutor.awaitTermination(5, TimeUnit.SECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
oldExecutor.shutdownNow();
|
||||
replaceExecutor(executors, type, true, false);
|
||||
} else {
|
||||
try {
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
oldExecutor.awaitTermination(5, TimeUnit.SECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -104,7 +104,7 @@ public class CatimaImporter implements Importer
|
||||
|
||||
public void parseV1(Context context, DBHelper db, BufferedReader input) throws IOException, FormatException, InterruptedException
|
||||
{
|
||||
final CSVParser parser = new CSVParser(input, CSVFormat.RFC4180.withHeader());
|
||||
final CSVParser parser = new CSVParser(input, CSVFormat.RFC4180.builder().setHeader().build());
|
||||
|
||||
SQLiteDatabase database = db.getWritableDatabase();
|
||||
database.beginTransaction();
|
||||
@@ -209,7 +209,7 @@ public class CatimaImporter implements Importer
|
||||
public void parseV2Groups(DBHelper db, SQLiteDatabase database, String data) throws IOException, FormatException, InterruptedException
|
||||
{
|
||||
// Parse groups
|
||||
final CSVParser groupParser = new CSVParser(new StringReader(data), CSVFormat.RFC4180.withHeader());
|
||||
final CSVParser groupParser = new CSVParser(new StringReader(data), CSVFormat.RFC4180.builder().setHeader().build());
|
||||
|
||||
List<CSVRecord> records = new ArrayList<>();
|
||||
|
||||
@@ -235,7 +235,7 @@ public class CatimaImporter implements Importer
|
||||
public void parseV2Cards(Context context, DBHelper db, SQLiteDatabase database, String data) throws IOException, FormatException, InterruptedException
|
||||
{
|
||||
// Parse cards
|
||||
final CSVParser cardParser = new CSVParser(new StringReader(data), CSVFormat.RFC4180.withHeader());
|
||||
final CSVParser cardParser = new CSVParser(new StringReader(data), CSVFormat.RFC4180.builder().setHeader().build());
|
||||
|
||||
List<CSVRecord> records = new ArrayList<>();
|
||||
|
||||
@@ -261,7 +261,7 @@ public class CatimaImporter implements Importer
|
||||
public void parseV2CardGroups(DBHelper db, SQLiteDatabase database, String data) throws IOException, FormatException, InterruptedException
|
||||
{
|
||||
// Parse card group mappings
|
||||
final CSVParser cardGroupParser = new CSVParser(new StringReader(data), CSVFormat.RFC4180.withHeader());
|
||||
final CSVParser cardGroupParser = new CSVParser(new StringReader(data), CSVFormat.RFC4180.builder().setHeader().build());
|
||||
|
||||
List<CSVRecord> records = new ArrayList<>();
|
||||
|
||||
|
||||
@@ -32,8 +32,7 @@ import protect.card_locker.Utils;
|
||||
* The database's loyalty cards are expected to appear in the CSV data.
|
||||
* A header is expected for the each table showing the names of the columns.
|
||||
*/
|
||||
public class FidmeImporter implements Importer
|
||||
{
|
||||
public class FidmeImporter implements Importer {
|
||||
public void importData(Context context, DBHelper db, InputStream input, char[] password) throws IOException, FormatException, JSONException, ParseException {
|
||||
// We actually retrieve a .zip file
|
||||
ZipInputStream zipInputStream = new ZipInputStream(input, password);
|
||||
@@ -59,7 +58,7 @@ public class FidmeImporter implements Importer
|
||||
SQLiteDatabase database = db.getWritableDatabase();
|
||||
database.beginTransaction();
|
||||
|
||||
final CSVParser fidmeParser = new CSVParser(new StringReader(loyaltyCards.toString()), CSVFormat.RFC4180.withDelimiter(';').withHeader());
|
||||
final CSVParser fidmeParser = new CSVParser(new StringReader(loyaltyCards.toString()), CSVFormat.RFC4180.builder().setDelimiter(';').setHeader().build());
|
||||
|
||||
try {
|
||||
for (CSVRecord record : fidmeParser) {
|
||||
@@ -87,8 +86,7 @@ public class FidmeImporter implements Importer
|
||||
* session.
|
||||
*/
|
||||
private void importLoyaltyCard(SQLiteDatabase database, DBHelper helper, CSVRecord record)
|
||||
throws IOException, FormatException
|
||||
{
|
||||
throws IOException, FormatException {
|
||||
// A loyalty card export from Fidme contains the following fields:
|
||||
// Retailer (store name)
|
||||
// Program (program name)
|
||||
@@ -100,8 +98,7 @@ public class FidmeImporter implements Importer
|
||||
// The store is called Retailer
|
||||
String store = CSVHelpers.extractString("Retailer", record, "");
|
||||
|
||||
if (store.isEmpty())
|
||||
{
|
||||
if (store.isEmpty()) {
|
||||
throw new FormatException("No store listed, but is required");
|
||||
}
|
||||
|
||||
@@ -121,8 +118,7 @@ public class FidmeImporter implements Importer
|
||||
|
||||
// The ID is called reference
|
||||
String cardId = CSVHelpers.extractString("Reference", record, "");
|
||||
if(cardId.isEmpty())
|
||||
{
|
||||
if (cardId.isEmpty()) {
|
||||
throw new FormatException("No card ID listed, but is required");
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ public class StocardImporter implements Importer
|
||||
HashMap<String, HashMap<String, Object>> loyaltyCardHashMap = new HashMap<>();
|
||||
HashMap<String, HashMap<String, String>> providers = new HashMap<>();
|
||||
|
||||
final CSVParser parser = new CSVParser(new InputStreamReader(context.getResources().openRawResource(R.raw.stocard_stores), StandardCharsets.UTF_8), CSVFormat.RFC4180.withHeader());
|
||||
final CSVParser parser = new CSVParser(new InputStreamReader(context.getResources().openRawResource(R.raw.stocard_stores), StandardCharsets.UTF_8), CSVFormat.RFC4180.builder().setHeader().build());
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user