Initial commit of application
8
.gitignore
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea/workspace.xml
|
||||
/.idea/libraries
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
||||
1
app/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/build
|
||||
38
app/build.gradle
Normal file
@@ -0,0 +1,38 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 23
|
||||
buildToolsVersion "23.0.2"
|
||||
|
||||
defaultConfig {
|
||||
applicationId "protect.card_locker"
|
||||
minSdkVersion 17
|
||||
targetSdkVersion 23
|
||||
versionCode 1
|
||||
versionName "0.1"
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
lintOptions {
|
||||
disable "GoogleAppIndexingWarning"
|
||||
disable "ButtonStyle"
|
||||
disable "AlwaysShowAction"
|
||||
}
|
||||
|
||||
// This is for Robolectric support for SDK 23
|
||||
useLibrary 'org.apache.http.legacy'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
compile 'com.android.support:appcompat-v7:23.1.1'
|
||||
compile 'com.android.support:design:23.1.1'
|
||||
compile 'com.journeyapps:zxing-android-embedded:3.0.1@aar'
|
||||
compile 'com.google.zxing:core:3.2.0'
|
||||
testCompile 'junit:junit:4.12'
|
||||
testCompile "org.robolectric:robolectric:3.0"
|
||||
}
|
||||
17
app/proguard-rules.pro
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in /Users/brarcher/Library/Android/sdk/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the proguardFiles
|
||||
# directive in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
@@ -0,0 +1,15 @@
|
||||
package protect.card_locker;
|
||||
|
||||
import android.app.Application;
|
||||
import android.test.ApplicationTestCase;
|
||||
|
||||
/**
|
||||
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
|
||||
*/
|
||||
public class ApplicationTest extends ApplicationTestCase<Application>
|
||||
{
|
||||
public ApplicationTest()
|
||||
{
|
||||
super(Application.class);
|
||||
}
|
||||
}
|
||||
31
app/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest package="protect.card_locker"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<uses-feature android:required="true" android:name="android.hardware.camera"/>
|
||||
<uses-permission android:maxSdkVersion="18" android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
|
||||
<application
|
||||
android:allowBackup="false"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity
|
||||
android:name="protect.card_locker.MainActivity"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme.NoActionBar">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".LoyaltyCardViewActivity"
|
||||
android:theme="@style/AppTheme.NoActionBar"
|
||||
android:configChanges="orientation|screenSize"
|
||||
android:parentActivityName="protect.card_locker.MainActivity"/>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
128
app/src/main/java/protect/card_locker/DBHelper.java
Normal file
@@ -0,0 +1,128 @@
|
||||
package protect.card_locker;
|
||||
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
|
||||
public class DBHelper extends SQLiteOpenHelper
|
||||
{
|
||||
public static final String DATABASE_NAME = "LoyaltyCards.db";
|
||||
public static final int DATABASE_VERSION = 1;
|
||||
|
||||
class LoyaltyCardDbIds
|
||||
{
|
||||
public static final String TABLE = "cards";
|
||||
public static final String ID = "_id";
|
||||
public static final String STORE = "store";
|
||||
public static final String CARD_ID = "cardid";
|
||||
public static final String BARCODE_TYPE = "barcodetype";
|
||||
}
|
||||
|
||||
public DBHelper(Context context)
|
||||
{
|
||||
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(SQLiteDatabase db)
|
||||
{
|
||||
// create table for gift cards
|
||||
db.execSQL("create table " + LoyaltyCardDbIds.TABLE + "(" +
|
||||
LoyaltyCardDbIds.ID + " INTEGER primary key autoincrement," +
|
||||
LoyaltyCardDbIds.STORE + " TEXT not null," +
|
||||
LoyaltyCardDbIds.CARD_ID + " TEXT not null," +
|
||||
LoyaltyCardDbIds.BARCODE_TYPE + " TEXT not null)");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
|
||||
{
|
||||
// Do not support versioning yet
|
||||
db.execSQL("DROP TABLE IF EXISTS " + LoyaltyCardDbIds.TABLE);
|
||||
onCreate(db);
|
||||
}
|
||||
|
||||
public boolean insertLoyaltyCard(final String store, final String cardId, final String barcodeType)
|
||||
{
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
ContentValues contentValues = new ContentValues();
|
||||
contentValues.put(LoyaltyCardDbIds.STORE, store);
|
||||
contentValues.put(LoyaltyCardDbIds.CARD_ID, cardId);
|
||||
contentValues.put(LoyaltyCardDbIds.BARCODE_TYPE, barcodeType);
|
||||
final long newId = db.insert(LoyaltyCardDbIds.TABLE, null, contentValues);
|
||||
return (newId != -1);
|
||||
}
|
||||
|
||||
|
||||
public boolean updateLoyaltyCard(final int id, final String store, final String cardId,
|
||||
final String barcodeType)
|
||||
{
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
ContentValues contentValues = new ContentValues();
|
||||
contentValues.put(LoyaltyCardDbIds.STORE, store);
|
||||
contentValues.put(LoyaltyCardDbIds.CARD_ID, cardId);
|
||||
contentValues.put(LoyaltyCardDbIds.BARCODE_TYPE, barcodeType);
|
||||
int rowsUpdated = db.update(LoyaltyCardDbIds.TABLE, contentValues,
|
||||
LoyaltyCardDbIds.ID + "=?",
|
||||
new String[]{Integer.toString(id)});
|
||||
return (rowsUpdated == 1);
|
||||
}
|
||||
|
||||
public LoyaltyCard getLoyaltyCard(final int id)
|
||||
{
|
||||
SQLiteDatabase db = getReadableDatabase();
|
||||
Cursor data = db.rawQuery("select * from " + LoyaltyCardDbIds.TABLE +
|
||||
" where " + LoyaltyCardDbIds.ID + "=?", new String[]{String.format("%d", id)});
|
||||
|
||||
LoyaltyCard card = null;
|
||||
|
||||
if(data.getCount() == 1)
|
||||
{
|
||||
data.moveToFirst();
|
||||
card = LoyaltyCard.toLoyaltyCard(data);
|
||||
}
|
||||
|
||||
data.close();
|
||||
|
||||
return card;
|
||||
}
|
||||
|
||||
public boolean deleteLoyaltyCard (final int id)
|
||||
{
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
int rowsDeleted = db.delete(LoyaltyCardDbIds.TABLE,
|
||||
LoyaltyCardDbIds.ID + " = ? ",
|
||||
new String[]{String.format("%d", id)});
|
||||
return (rowsDeleted == 1);
|
||||
}
|
||||
|
||||
public Cursor getLoyaltyCardCursor()
|
||||
{
|
||||
SQLiteDatabase db = getReadableDatabase();
|
||||
Cursor res = db.rawQuery("select * from " + LoyaltyCardDbIds.TABLE +
|
||||
" ORDER BY " + LoyaltyCardDbIds.STORE, null);
|
||||
return res;
|
||||
}
|
||||
|
||||
public int getLoyaltyCardCount()
|
||||
{
|
||||
SQLiteDatabase db = getReadableDatabase();
|
||||
Cursor data = db.rawQuery("SELECT Count(*) FROM " + LoyaltyCardDbIds.TABLE, null);
|
||||
|
||||
int numItems = 0;
|
||||
|
||||
if(data.getCount() == 1)
|
||||
{
|
||||
data.moveToFirst();
|
||||
numItems = data.getInt(0);
|
||||
}
|
||||
|
||||
data.close();
|
||||
|
||||
return numItems;
|
||||
}
|
||||
}
|
||||
|
||||
29
app/src/main/java/protect/card_locker/LoyaltyCard.java
Normal file
@@ -0,0 +1,29 @@
|
||||
package protect.card_locker;
|
||||
|
||||
import android.database.Cursor;
|
||||
|
||||
public class LoyaltyCard
|
||||
{
|
||||
public final int id;
|
||||
public final String store;
|
||||
public final String cardId;
|
||||
public final String barcodeType;
|
||||
|
||||
public LoyaltyCard(final int id, final String store, final String cardId, final String barcodeType)
|
||||
{
|
||||
this.id = id;
|
||||
this.store = store;
|
||||
this.cardId = cardId;
|
||||
this.barcodeType = barcodeType;
|
||||
}
|
||||
|
||||
public static LoyaltyCard toLoyaltyCard(Cursor cursor)
|
||||
{
|
||||
int id = cursor.getInt(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.ID));
|
||||
String store = cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.STORE));
|
||||
String cardId = cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.CARD_ID));
|
||||
String barcodeType = cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.BARCODE_TYPE));
|
||||
|
||||
return new LoyaltyCard(id, store, cardId, barcodeType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package protect.card_locker;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CursorAdapter;
|
||||
import android.widget.TextView;
|
||||
|
||||
class LoyaltyCardCursorAdapter extends CursorAdapter
|
||||
{
|
||||
public LoyaltyCardCursorAdapter(Context context, Cursor cursor)
|
||||
{
|
||||
super(context, cursor, 0);
|
||||
}
|
||||
|
||||
// The newView method is used to inflate a new view and return it,
|
||||
// you don't bind any data to the view at this point.
|
||||
@Override
|
||||
public View newView(Context context, Cursor cursor, ViewGroup parent)
|
||||
{
|
||||
return LayoutInflater.from(context).inflate(R.layout.loyalty_card_layout, parent, false);
|
||||
}
|
||||
|
||||
// The bindView method is used to bind all data to a given view
|
||||
// such as setting the text on a TextView.
|
||||
@Override
|
||||
public void bindView(View view, Context context, Cursor cursor)
|
||||
{
|
||||
// Find fields to populate in inflated template
|
||||
TextView storeField = (TextView) view.findViewById(R.id.store);
|
||||
TextView cardIdField = (TextView) view.findViewById(R.id.cardId);
|
||||
|
||||
// Extract properties from cursor
|
||||
LoyaltyCard loyaltyCard = LoyaltyCard.toLoyaltyCard(cursor);
|
||||
|
||||
// Populate fields with extracted properties
|
||||
storeField.setText(loyaltyCard.store);
|
||||
|
||||
String cardIdFormat = view.getResources().getString(R.string.cardIdFormat);
|
||||
String cardIdLabel = view.getResources().getString(R.string.cardId);
|
||||
String cardIdText = String.format(cardIdFormat, cardIdLabel, loyaltyCard.cardId);
|
||||
cardIdField.setText(cardIdText);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,301 @@
|
||||
package protect.card_locker;
|
||||
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.os.Bundle;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
import com.google.zxing.MultiFormatWriter;
|
||||
import com.google.zxing.WriterException;
|
||||
import com.google.zxing.common.BitMatrix;
|
||||
import com.google.zxing.integration.android.IntentIntegrator;
|
||||
import com.google.zxing.integration.android.IntentResult;
|
||||
|
||||
|
||||
public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
{
|
||||
private static final String TAG = "CardLocker";
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.loyalty_card_view_activity);
|
||||
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
if(actionBar != null)
|
||||
{
|
||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
|
||||
final Bundle b = getIntent().getExtras();
|
||||
final int loyaltyCardId = b != null ? b.getInt("id") : 0;
|
||||
final boolean updateLoyaltyCard = b != null && b.getBoolean("update", false);
|
||||
final boolean viewLoyaltyCard = b != null && b.getBoolean("view", false);
|
||||
|
||||
Log.i(TAG, "To view card: " + loyaltyCardId);
|
||||
|
||||
final EditText storeField = (EditText) findViewById(R.id.storeName);
|
||||
final EditText cardIdField = (EditText) findViewById(R.id.cardId);
|
||||
final EditText barcodeTypeField = (EditText) findViewById(R.id.barcodeType);
|
||||
final ImageView barcodeImage = (ImageView) findViewById(R.id.barcode);
|
||||
final View barcodeIdLayout = findViewById(R.id.barcodeIdLayout);
|
||||
final View barcodeTypeLayout = findViewById(R.id.barcodeTypeLayout);
|
||||
final View barcodeImageLayout = findViewById(R.id.barcodeLayout);
|
||||
final View barcodeCaptureLayout = findViewById(R.id.barcodeCaptureLayout);
|
||||
|
||||
final Button captureButton = (Button) findViewById(R.id.captureButton);
|
||||
final Button saveButton = (Button) findViewById(R.id.saveButton);
|
||||
final Button cancelButton = (Button) findViewById(R.id.cancelButton);
|
||||
|
||||
final DBHelper db = new DBHelper(this);
|
||||
|
||||
if(updateLoyaltyCard || viewLoyaltyCard)
|
||||
{
|
||||
final LoyaltyCard loyaltyCard = db.getLoyaltyCard(loyaltyCardId);
|
||||
|
||||
storeField.setText(loyaltyCard.store);
|
||||
|
||||
if(cardIdField.getText().length() == 0)
|
||||
{
|
||||
cardIdField.setText(loyaltyCard.cardId);
|
||||
}
|
||||
|
||||
if(barcodeTypeField.getText().length() == 0)
|
||||
{
|
||||
barcodeTypeField.setText(loyaltyCard.barcodeType);
|
||||
}
|
||||
|
||||
storeField.setEnabled(false);
|
||||
|
||||
if(updateLoyaltyCard)
|
||||
{
|
||||
setTitle(R.string.editCardTitle);
|
||||
}
|
||||
else
|
||||
{
|
||||
barcodeCaptureLayout.setVisibility(View.GONE);
|
||||
captureButton.setVisibility(View.GONE);
|
||||
saveButton.setVisibility(View.GONE);
|
||||
cancelButton.setVisibility(View.GONE);
|
||||
setTitle(R.string.viewCardTitle);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
setTitle(R.string.addCardTitle);
|
||||
}
|
||||
|
||||
if(cardIdField.getText().length() == 0)
|
||||
{
|
||||
barcodeIdLayout.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
barcodeTypeLayout.setVisibility(View.GONE);
|
||||
|
||||
if(cardIdField.getText().length() > 0 && barcodeTypeField.getText().length() > 0)
|
||||
{
|
||||
MultiFormatWriter writer = new MultiFormatWriter();
|
||||
BitMatrix result;
|
||||
try
|
||||
{
|
||||
String formatString = barcodeTypeField.getText().toString();
|
||||
BarcodeFormat format = BarcodeFormat.valueOf(formatString);
|
||||
if(format == null)
|
||||
{
|
||||
throw new IllegalArgumentException("Unrecognized barcode format: " + formatString);
|
||||
}
|
||||
|
||||
String cardIdString = cardIdField.getText().toString();
|
||||
|
||||
Log.i(TAG, "Card: " + cardIdString);
|
||||
|
||||
result = writer.encode(cardIdString, format, 1500, 400, null);
|
||||
|
||||
final int WHITE = 0xFFFFFFFF;
|
||||
final int BLACK = 0xFF000000;
|
||||
|
||||
int width = result.getWidth();
|
||||
int height = result.getHeight();
|
||||
int[] pixels = new int[width * height];
|
||||
for (int y = 0; y < height; y++)
|
||||
{
|
||||
int offset = y * width;
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
pixels[offset + x] = result.get(x, y) ? BLACK : WHITE;
|
||||
}
|
||||
}
|
||||
Bitmap bitmap = Bitmap.createBitmap(width, height,
|
||||
Bitmap.Config.ARGB_8888);
|
||||
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
|
||||
barcodeImage.setImageBitmap(bitmap);
|
||||
|
||||
barcodeIdLayout.setVisibility(View.VISIBLE);
|
||||
barcodeImageLayout.setVisibility(View.VISIBLE);
|
||||
}
|
||||
catch (WriterException e)
|
||||
{
|
||||
Log.e(TAG, "Failed to generate barcode", e);
|
||||
}
|
||||
catch(IllegalArgumentException e)
|
||||
{
|
||||
Log.e(TAG, "Failed to generate barcode", e);
|
||||
}
|
||||
}
|
||||
|
||||
View.OnClickListener captureCallback = new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
IntentIntegrator integrator = new IntentIntegrator(LoyaltyCardViewActivity.this);
|
||||
integrator.setDesiredBarcodeFormats(IntentIntegrator.PRODUCT_CODE_TYPES);
|
||||
|
||||
String prompt = getResources().getString(R.string.scanCardBarcode);
|
||||
integrator.setPrompt(prompt);
|
||||
integrator.initiateScan();
|
||||
}
|
||||
};
|
||||
|
||||
captureButton.setOnClickListener(captureCallback);
|
||||
|
||||
saveButton.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(final View v)
|
||||
{
|
||||
String store = storeField.getText().toString();
|
||||
String cardId = cardIdField.getText().toString();
|
||||
String barcodeType = barcodeTypeField.getText().toString();
|
||||
|
||||
if(store.isEmpty())
|
||||
{
|
||||
Snackbar.make(v, R.string.noStoreError, Snackbar.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if(cardId.isEmpty() || barcodeType.isEmpty())
|
||||
{
|
||||
Snackbar.make(v, R.string.noCardIdError, Snackbar.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if(updateLoyaltyCard)
|
||||
{
|
||||
db.updateLoyaltyCard(loyaltyCardId, store, cardId, barcodeType);
|
||||
Log.i(TAG, "Updated " + loyaltyCardId + " to " + cardId);
|
||||
}
|
||||
else
|
||||
{
|
||||
db.insertLoyaltyCard(store, cardId, barcodeType);
|
||||
}
|
||||
|
||||
finish();
|
||||
}
|
||||
});
|
||||
|
||||
cancelButton.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu)
|
||||
{
|
||||
final Bundle b = getIntent().getExtras();
|
||||
final boolean updateLoyaltyCard = b != null && b.getBoolean("update", false);
|
||||
final boolean viewLoyaltyCard = b != null && b.getBoolean("view", false);
|
||||
|
||||
if(viewLoyaltyCard)
|
||||
{
|
||||
getMenuInflater().inflate(R.menu.card_edit_menu, menu);
|
||||
}
|
||||
else if(updateLoyaltyCard)
|
||||
{
|
||||
getMenuInflater().inflate(R.menu.card_delete_menu, menu);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item)
|
||||
{
|
||||
int id = item.getItemId();
|
||||
|
||||
final Bundle b = getIntent().getExtras();
|
||||
final int loyaltyCardId = b != null ? b.getInt("id") : 0;
|
||||
|
||||
switch(id)
|
||||
{
|
||||
case R.id.action_delete:
|
||||
Log.e(TAG, "Deleting card: " + loyaltyCardId);
|
||||
|
||||
DBHelper db = new DBHelper(this);
|
||||
db.deleteLoyaltyCard(loyaltyCardId);
|
||||
finish();
|
||||
return true;
|
||||
case R.id.action_edit:
|
||||
Intent intent = new Intent(getApplicationContext(), LoyaltyCardViewActivity.class);
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt("id", loyaltyCardId);
|
||||
bundle.putBoolean("update", true);
|
||||
intent.putExtras(bundle);
|
||||
startActivity(intent);
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent intent)
|
||||
{
|
||||
IntentResult result =
|
||||
IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
|
||||
if (result != null)
|
||||
{
|
||||
String contents = result.getContents();
|
||||
String format = result.getFormatName();
|
||||
if(contents != null && contents.isEmpty() == false &&
|
||||
format != null && format.isEmpty() == false)
|
||||
{
|
||||
Log.i(TAG, "Read Contents from scan: " + contents);
|
||||
Log.i(TAG, "Read Format: " + format);
|
||||
|
||||
final EditText cardIdField = (EditText) findViewById(R.id.cardId);
|
||||
cardIdField.setText(contents);
|
||||
final EditText barcodeTypeField = (EditText) findViewById(R.id.barcodeType);
|
||||
barcodeTypeField.setText(format);
|
||||
onResume();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
97
app/src/main/java/protect/card_locker/MainActivity.java
Normal file
@@ -0,0 +1,97 @@
|
||||
package protect.card_locker;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
public class MainActivity extends AppCompatActivity
|
||||
{
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.main_activity);
|
||||
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
|
||||
updateLoyaltyCardList();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
|
||||
updateLoyaltyCardList();
|
||||
}
|
||||
|
||||
private void updateLoyaltyCardList()
|
||||
{
|
||||
final ListView cardList = (ListView) findViewById(R.id.list);
|
||||
final TextView helpText = (TextView) findViewById(R.id.helpText);
|
||||
final DBHelper db = new DBHelper(this);
|
||||
|
||||
if(db.getLoyaltyCardCount() > 0)
|
||||
{
|
||||
cardList.setVisibility(View.VISIBLE);
|
||||
helpText.setVisibility(View.GONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
cardList.setVisibility(View.GONE);
|
||||
helpText.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
Cursor cardCursor = db.getLoyaltyCardCursor();
|
||||
|
||||
final LoyaltyCardCursorAdapter adapter = new LoyaltyCardCursorAdapter(this, cardCursor);
|
||||
cardList.setAdapter(adapter);
|
||||
|
||||
cardList.setOnItemClickListener(new AdapterView.OnItemClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
|
||||
{
|
||||
Cursor selected = (Cursor) parent.getItemAtPosition(position);
|
||||
LoyaltyCard loyaltyCard = LoyaltyCard.toLoyaltyCard(selected);
|
||||
|
||||
Intent i = new Intent(view.getContext(), LoyaltyCardViewActivity.class);
|
||||
final Bundle b = new Bundle();
|
||||
b.putInt("id", loyaltyCard.id);
|
||||
b.putBoolean("view", true);
|
||||
i.putExtras(b);
|
||||
startActivity(i);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu)
|
||||
{
|
||||
getMenuInflater().inflate(R.menu.main_menu, menu);
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item)
|
||||
{
|
||||
int id = item.getItemId();
|
||||
|
||||
if (id == R.id.action_add)
|
||||
{
|
||||
Intent i = new Intent(getApplicationContext(), LoyaltyCardViewActivity.class);
|
||||
startActivity(i);
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
BIN
app/src/main/res/drawable-hdpi/ic_add_white_24dp.png
Normal file
|
After Width: | Height: | Size: 127 B |
BIN
app/src/main/res/drawable-hdpi/ic_delete_white_24dp.png
Normal file
|
After Width: | Height: | Size: 161 B |
BIN
app/src/main/res/drawable-hdpi/ic_mode_edit_white_24dp.png
Normal file
|
After Width: | Height: | Size: 219 B |
BIN
app/src/main/res/drawable-mdpi/ic_add_white_24dp.png
Normal file
|
After Width: | Height: | Size: 88 B |
BIN
app/src/main/res/drawable-mdpi/ic_delete_white_24dp.png
Normal file
|
After Width: | Height: | Size: 115 B |
BIN
app/src/main/res/drawable-mdpi/ic_mode_edit_white_24dp.png
Normal file
|
After Width: | Height: | Size: 165 B |
BIN
app/src/main/res/drawable-xhdpi/ic_add_white_24dp.png
Normal file
|
After Width: | Height: | Size: 97 B |
BIN
app/src/main/res/drawable-xhdpi/ic_delete_white_24dp.png
Normal file
|
After Width: | Height: | Size: 151 B |
BIN
app/src/main/res/drawable-xhdpi/ic_mode_edit_white_24dp.png
Normal file
|
After Width: | Height: | Size: 239 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_add_white_24dp.png
Normal file
|
After Width: | Height: | Size: 97 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_delete_white_24dp.png
Normal file
|
After Width: | Height: | Size: 194 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_mode_edit_white_24dp.png
Normal file
|
After Width: | Height: | Size: 302 B |
BIN
app/src/main/res/drawable-xxxhdpi/ic_add_white_24dp.png
Normal file
|
After Width: | Height: | Size: 102 B |
BIN
app/src/main/res/drawable-xxxhdpi/ic_delete_white_24dp.png
Normal file
|
After Width: | Height: | Size: 243 B |
BIN
app/src/main/res/drawable-xxxhdpi/ic_mode_edit_white_24dp.png
Normal file
|
After Width: | Height: | Size: 355 B |
29
app/src/main/res/layout/content_main.xml
Normal file
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||
android:paddingTop="@dimen/activity_vertical_margin"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||
tools:context="protect.card_locker.MainActivity"
|
||||
tools:showIn="@layout/main_activity">
|
||||
|
||||
<TextView
|
||||
style="@style/AppTheme.TextView.NoData"
|
||||
android:id="@+id/helpText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/noGiftCards"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<ListView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/list"
|
||||
android:visibility="gone"/>
|
||||
</RelativeLayout>
|
||||
31
app/src/main/res/layout/loyalty_card_layout.xml
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout android:orientation="vertical"
|
||||
android:padding="5.0dip"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<LinearLayout android:orientation="horizontal"
|
||||
android:padding="5.0dip"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:baselineAligned="true">
|
||||
<TextView android:textSize="20.0sp"
|
||||
android:id="@+id/store"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1.0"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout android:orientation="horizontal"
|
||||
android:padding="5.0dip"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:baselineAligned="true">
|
||||
<TextView android:textSize="20.0sp"
|
||||
android:layout_gravity="start"
|
||||
android:id="@+id/cardId"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
139
app/src/main/res/layout/loyalty_card_view_activity.xml
Normal file
@@ -0,0 +1,139 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
tools:context="protect.budgetwatch.AccountsActivity">
|
||||
|
||||
<android.support.design.widget.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:theme="@style/AppTheme.AppBarOverlay">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="?attr/colorPrimary"
|
||||
app:popupTheme="@style/AppTheme.PopupOverlay" />
|
||||
|
||||
</android.support.design.widget.AppBarLayout>
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||
android:id="@+id/scrollView">
|
||||
|
||||
<LinearLayout android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<LinearLayout android:orientation="horizontal"
|
||||
android:padding="10.0dip"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<TextView android:textSize="16.0sp"
|
||||
android:textStyle="bold"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:paddingStart="20.0dip"
|
||||
android:paddingEnd="20.0dip"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:labelFor="@+id/storeName"
|
||||
android:text="@string/storeName" />
|
||||
<LinearLayout android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<EditText android:id="@+id/storeName"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
<LinearLayout android:orientation="horizontal"
|
||||
android:padding="10.0dip"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/barcodeIdLayout">
|
||||
<TextView android:textSize="16.0sp"
|
||||
android:textStyle="bold"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:paddingStart="20.0dip"
|
||||
android:paddingEnd="20.0dip"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:labelFor="@+id/cardId"
|
||||
android:text="@string/cardId" />
|
||||
<EditText android:id="@+id/cardId"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:enabled="false"
|
||||
android:inputType="text"/>
|
||||
</LinearLayout>
|
||||
<LinearLayout android:orientation="horizontal"
|
||||
android:padding="10.0dip"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/barcodeTypeLayout">
|
||||
<TextView android:textSize="16.0sp"
|
||||
android:textStyle="bold"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:paddingStart="20.0dip"
|
||||
android:paddingEnd="20.0dip"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:labelFor="@+id/barcodeType"
|
||||
android:text="@string/barcodeType" />
|
||||
<EditText android:id="@+id/barcodeType"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:enabled="false"
|
||||
android:inputType="text"/>
|
||||
</LinearLayout>
|
||||
<LinearLayout android:orientation="horizontal"
|
||||
android:padding="10.0dip"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
android:id="@+id/barcodeLayout">
|
||||
<ImageView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/barcode_disp_height"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:id="@+id/barcode"
|
||||
android:contentDescription="@string/barcodeImageDescription"
|
||||
android:layout_weight="1.0"/>
|
||||
</LinearLayout>
|
||||
<LinearLayout android:orientation="horizontal"
|
||||
android:padding="10.0dip"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/barcodeCaptureLayout">
|
||||
<Button android:id="@+id/captureButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/capture"
|
||||
android:layout_weight="1.0"/>
|
||||
</LinearLayout>
|
||||
<LinearLayout android:orientation="horizontal"
|
||||
android:padding="10.0dip"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:baselineAligned="true">
|
||||
<Button android:id="@+id/cancelButton"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/cancel"
|
||||
android:layout_weight="1.0" />
|
||||
<Button android:id="@+id/saveButton"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/save"
|
||||
android:layout_weight="1.0" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
|
||||
</android.support.design.widget.CoordinatorLayout>
|
||||
27
app/src/main/res/layout/main_activity.xml
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.design.widget.CoordinatorLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
tools:context="protect.card_locker.MainActivity">
|
||||
|
||||
<android.support.design.widget.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:theme="@style/AppTheme.AppBarOverlay">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="?attr/colorPrimary"
|
||||
app:popupTheme="@style/AppTheme.PopupOverlay"/>
|
||||
|
||||
</android.support.design.widget.AppBarLayout>
|
||||
|
||||
<include layout="@layout/content_main"/>
|
||||
|
||||
</android.support.design.widget.CoordinatorLayout>
|
||||
10
app/src/main/res/menu/card_delete_menu.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/action_delete"
|
||||
android:icon="@drawable/ic_delete_white_24dp"
|
||||
android:title="@string/delete"
|
||||
app:showAsAction="always"/>
|
||||
</menu>
|
||||
10
app/src/main/res/menu/card_edit_menu.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/action_edit"
|
||||
android:icon="@drawable/ic_mode_edit_white_24dp"
|
||||
android:title="@string/edit"
|
||||
app:showAsAction="always"/>
|
||||
</menu>
|
||||
10
app/src/main/res/menu/main_menu.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:context="protect.card_locker.MainActivity">
|
||||
<item
|
||||
android:id="@+id/action_add"
|
||||
android:icon="@drawable/ic_add_white_24dp"
|
||||
android:title="@string/action_add"
|
||||
app:showAsAction="always"/>
|
||||
</menu>
|
||||
BIN
app/src/main/res/mipmap-hdpi/ic_launcher.png
Executable file
|
After Width: | Height: | Size: 1012 B |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher.png
Executable file
|
After Width: | Height: | Size: 676 B |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher.png
Executable file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Executable file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Executable file
|
After Width: | Height: | Size: 2.5 KiB |
9
app/src/main/res/values-v21/styles.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<resources>>
|
||||
|
||||
<style name="AppTheme.NoActionBar">
|
||||
<item name="windowActionBar">false</item>
|
||||
<item name="windowNoTitle">true</item>
|
||||
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
|
||||
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||
</style>
|
||||
</resources>
|
||||
6
app/src/main/res/values-w820dp/dimens.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<resources>
|
||||
<!-- Example customization of dimensions originally defined in res/values/dimens.xml
|
||||
(such as screen margins) for screens with more than 820dp of available width. This
|
||||
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
|
||||
<dimen name="activity_horizontal_margin">64dp</dimen>
|
||||
</resources>
|
||||
7
app/src/main/res/values/colors.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Palette generated by Material Palette - materialpalette.com/green/blue-grey -->
|
||||
<resources>
|
||||
<color name="colorPrimary">#4CAF50</color>
|
||||
<color name="colorPrimaryDark">#388E3C</color>
|
||||
<color name="colorAccent">#607D8B</color>
|
||||
</resources>
|
||||
10
app/src/main/res/values/dimens.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<resources>
|
||||
<!-- Default screen margins, per the Android Design guidelines. -->
|
||||
<dimen name="activity_horizontal_margin">16dp</dimen>
|
||||
<dimen name="activity_vertical_margin">16dp</dimen>
|
||||
|
||||
<dimen name="no_data_textSize">16sp</dimen>
|
||||
<dimen name="no_data_padding">22dp</dimen>
|
||||
|
||||
<dimen name="barcode_disp_height">50dp</dimen>
|
||||
</resources>
|
||||
28
app/src/main/res/values/strings.xml
Normal file
@@ -0,0 +1,28 @@
|
||||
<resources>
|
||||
<string name="app_name">Loyalty Card Locker</string>
|
||||
<string name="action_add">Add</string>
|
||||
|
||||
<string name="noGiftCards">You don\'t have any loyalty cards at the moment. Click the "+" (plus) button up top to get started.\n\nLoyalty Card Locker lets you carry your loyalty cards on your phone, so they are always within reach.</string>
|
||||
|
||||
<string name="storeName">Store</string>
|
||||
<string name="cardId">Card ID</string>
|
||||
<string name="barcodeType">Barcode Type</string>
|
||||
|
||||
<string name="cancel">Cancel</string>
|
||||
<string name="save">Save</string>
|
||||
<string name="capture">Capture Card</string>
|
||||
<string name="edit">Edit</string>
|
||||
<string name="delete">Delete</string>
|
||||
|
||||
<string name="editCardTitle">Edit Loyalty Card</string>
|
||||
<string name="addCardTitle">Add Loyalty Card</string>
|
||||
<string name="viewCardTitle">View Loyalty Card</string>
|
||||
<string name="scanCardBarcode">Scan Card\'s Barcode</string>
|
||||
|
||||
<string name="barcodeImageDescription">Image of card\'s barcode</string>
|
||||
|
||||
<string name="noStoreError">No Store entered</string>
|
||||
<string name="noCardIdError">No Card ID entered</string>
|
||||
|
||||
<string name="cardIdFormat">%1$s: %2$s</string>
|
||||
</resources>
|
||||
27
app/src/main/res/values/styles.xml
Normal file
@@ -0,0 +1,27 @@
|
||||
<resources>
|
||||
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
</style>
|
||||
|
||||
<style name="AppTheme.NoActionBar">
|
||||
<item name="windowActionBar">false</item>
|
||||
<item name="windowNoTitle">true</item>
|
||||
</style>
|
||||
|
||||
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar"/>
|
||||
|
||||
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light"/>
|
||||
|
||||
<style name="AppTheme.TextView.NoData" parent="AppTheme">
|
||||
<item name="android:layout_centerHorizontal">true</item>
|
||||
<item name="android:layout_centerVertical">true</item>
|
||||
<item name="android:padding">@dimen/no_data_padding</item>
|
||||
<item name="android:textSize">@dimen/no_data_textSize</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
128
app/src/test/java/protect/card_locker/DatabaseTest.java
Normal file
@@ -0,0 +1,128 @@
|
||||
package protect.card_locker;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.database.Cursor;
|
||||
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricGradleTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
@RunWith(RobolectricGradleTestRunner.class)
|
||||
@Config(constants = BuildConfig.class, sdk = 17)
|
||||
public class DatabaseTest
|
||||
{
|
||||
private DBHelper db;
|
||||
|
||||
@Before
|
||||
public void setUp()
|
||||
{
|
||||
Activity activity = Robolectric.setupActivity(MainActivity.class);
|
||||
db = new DBHelper(activity);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addRemoveOneGiftCard()
|
||||
{
|
||||
assertEquals(0, db.getLoyaltyCardCount());
|
||||
boolean result = db.insertLoyaltyCard("store", "cardId", BarcodeFormat.UPC_A.toString());
|
||||
assertTrue(result);
|
||||
assertEquals(1, db.getLoyaltyCardCount());
|
||||
|
||||
LoyaltyCard loyaltyCard = db.getLoyaltyCard(1);
|
||||
assertNotNull(loyaltyCard);
|
||||
assertEquals("store", loyaltyCard.store);
|
||||
assertEquals("cardId", loyaltyCard.cardId);
|
||||
assertEquals(BarcodeFormat.UPC_A.toString(), loyaltyCard.barcodeType);
|
||||
|
||||
result = db.deleteLoyaltyCard(1);
|
||||
assertTrue(result);
|
||||
assertEquals(0, db.getLoyaltyCardCount());
|
||||
assertNull(db.getLoyaltyCard(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateGiftCard()
|
||||
{
|
||||
boolean result = db.insertLoyaltyCard("store", "cardId", BarcodeFormat.UPC_A.toString());
|
||||
assertTrue(result);
|
||||
assertEquals(1, db.getLoyaltyCardCount());
|
||||
|
||||
result = db.updateLoyaltyCard(1, "store1", "cardId1", BarcodeFormat.AZTEC.toString());
|
||||
assertTrue(result);
|
||||
assertEquals(1, db.getLoyaltyCardCount());
|
||||
|
||||
LoyaltyCard loyaltyCard = db.getLoyaltyCard(1);
|
||||
assertNotNull(loyaltyCard);
|
||||
assertEquals("store1", loyaltyCard.store);
|
||||
assertEquals("cardId1", loyaltyCard.cardId);
|
||||
assertEquals(BarcodeFormat.AZTEC.toString(), loyaltyCard.barcodeType);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateMissingGiftCard()
|
||||
{
|
||||
assertEquals(0, db.getLoyaltyCardCount());
|
||||
|
||||
boolean result = db.updateLoyaltyCard(1, "store1", "cardId1", BarcodeFormat.UPC_A.toString());
|
||||
assertEquals(false, result);
|
||||
assertEquals(0, db.getLoyaltyCardCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void emptyGiftCardValues()
|
||||
{
|
||||
boolean result = db.insertLoyaltyCard("", "", "");
|
||||
assertTrue(result);
|
||||
assertEquals(1, db.getLoyaltyCardCount());
|
||||
|
||||
LoyaltyCard loyaltyCard = db.getLoyaltyCard(1);
|
||||
assertNotNull(loyaltyCard);
|
||||
assertEquals("", loyaltyCard.store);
|
||||
assertEquals("", loyaltyCard.cardId);
|
||||
assertEquals("", loyaltyCard.barcodeType);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void giftCardsViaCursor()
|
||||
{
|
||||
final int CARDS_TO_ADD = 10;
|
||||
|
||||
// Add the gift cards in reverse order, to ensure
|
||||
// that they are sorted
|
||||
for(int index = CARDS_TO_ADD-1; index >= 0; index--)
|
||||
{
|
||||
boolean result = db.insertLoyaltyCard("store" + index, "cardId" + index, BarcodeFormat.UPC_A.toString());
|
||||
assertTrue(result);
|
||||
}
|
||||
|
||||
assertEquals(CARDS_TO_ADD, db.getLoyaltyCardCount());
|
||||
|
||||
Cursor cursor = db.getLoyaltyCardCursor();
|
||||
assertNotNull(cursor);
|
||||
|
||||
assertEquals(CARDS_TO_ADD, cursor.getCount());
|
||||
|
||||
cursor.moveToFirst();
|
||||
|
||||
for(int index = 0; index < CARDS_TO_ADD; index++)
|
||||
{
|
||||
assertEquals("store"+index, cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.STORE)));
|
||||
assertEquals("cardId"+index, cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.CARD_ID)));
|
||||
assertEquals(BarcodeFormat.UPC_A.toString(), cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.BARCODE_TYPE)));
|
||||
|
||||
cursor.moveToNext();
|
||||
}
|
||||
|
||||
assertTrue(cursor.isAfterLast());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package protect.card_locker;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.database.Cursor;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricGradleTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.util.ActivityController;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
@RunWith(RobolectricGradleTestRunner.class)
|
||||
@Config(constants = BuildConfig.class, sdk = 17)
|
||||
public class LoyaltyCardCursorAdapterTest
|
||||
{
|
||||
@Test
|
||||
public void TestCursorAdapter()
|
||||
{
|
||||
ActivityController activityController = Robolectric.buildActivity(MainActivity.class).create();
|
||||
Activity activity = (Activity)activityController.get();
|
||||
|
||||
DBHelper db = new DBHelper(activity);
|
||||
db.insertLoyaltyCard("store", "cardId", BarcodeFormat.UPC_A.toString());
|
||||
LoyaltyCard card = db.getLoyaltyCard(1);
|
||||
|
||||
Cursor cursor = db.getLoyaltyCardCursor();
|
||||
cursor.moveToFirst();
|
||||
|
||||
LoyaltyCardCursorAdapter adapter = new LoyaltyCardCursorAdapter(activity.getApplicationContext(), cursor);
|
||||
|
||||
View view = adapter.newView(activity.getApplicationContext(), cursor, null);
|
||||
adapter.bindView(view, activity.getApplicationContext(), cursor);
|
||||
|
||||
final TextView storeField = (TextView) view.findViewById(R.id.store);
|
||||
|
||||
assertEquals(card.store, storeField.getText().toString());
|
||||
|
||||
final TextView cardIdField = (TextView) view.findViewById(R.id.cardId);
|
||||
final String cardIdLabel = activity.getResources().getString(R.string.cardId);
|
||||
final String cardIdFormat = activity.getResources().getString(R.string.cardIdFormat);
|
||||
String cardIdText = String.format(cardIdFormat, cardIdLabel, "cardId");
|
||||
assertEquals(cardIdText, cardIdField.getText().toString());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,372 @@
|
||||
package protect.card_locker;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
import com.google.zxing.client.android.Intents;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricGradleTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.res.builder.RobolectricPackageManager;
|
||||
import org.robolectric.shadows.ShadowActivity;
|
||||
import org.robolectric.util.ActivityController;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.robolectric.Shadows.shadowOf;
|
||||
|
||||
@RunWith(RobolectricGradleTestRunner.class)
|
||||
@Config(constants = BuildConfig.class, sdk = 17)
|
||||
public class LoyaltyCardViewActivityTest
|
||||
{
|
||||
private final String BARCODE_DATA = "428311627547";
|
||||
private final String BARCODE_TYPE = BarcodeFormat.UPC_A.name();
|
||||
|
||||
private final String EAN_BARCODE_DATA = "4763705295336";
|
||||
private final String EAN_BARCODE_TYPE = BarcodeFormat.EAN_13.name();
|
||||
|
||||
/**
|
||||
* Register a handler in the package manager for a image capture intent
|
||||
*/
|
||||
private void registerMediaStoreIntentHandler()
|
||||
{
|
||||
// Add something that will 'handle' the media capture intent
|
||||
RobolectricPackageManager packageManager = (RobolectricPackageManager) shadowOf(
|
||||
RuntimeEnvironment.application).getPackageManager();
|
||||
|
||||
ResolveInfo info = new ResolveInfo();
|
||||
info.isDefault = true;
|
||||
|
||||
ApplicationInfo applicationInfo = new ApplicationInfo();
|
||||
applicationInfo.packageName = "does.not.matter";
|
||||
info.activityInfo = new ActivityInfo();
|
||||
info.activityInfo.applicationInfo = applicationInfo;
|
||||
info.activityInfo.name = "DoesNotMatter";
|
||||
|
||||
Intent intent = new Intent(Intents.Scan.ACTION);
|
||||
|
||||
packageManager.addResolveInfoForIntent(intent, info);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a loyalty card and check that the database contains the
|
||||
* expected values
|
||||
*/
|
||||
private void saveLoyaltyCardWithArguments(final Activity activity,
|
||||
final String store, final String cardId,
|
||||
final String barcodeType,
|
||||
boolean creatingNewCard)
|
||||
{
|
||||
DBHelper db = new DBHelper(activity);
|
||||
if(creatingNewCard)
|
||||
{
|
||||
assertEquals(0, db.getLoyaltyCardCount());
|
||||
}
|
||||
else
|
||||
{
|
||||
assertEquals(1, db.getLoyaltyCardCount());
|
||||
}
|
||||
|
||||
final EditText storeField = (EditText) activity.findViewById(R.id.storeName);
|
||||
final EditText cardIdField = (EditText) activity.findViewById(R.id.cardId);
|
||||
final EditText barcodeTypeField = (EditText) activity.findViewById(R.id.barcodeType);
|
||||
|
||||
final Button saveButton = (Button) activity.findViewById(R.id.saveButton);
|
||||
|
||||
storeField.setText(store);
|
||||
cardIdField.setText(cardId);
|
||||
barcodeTypeField.setText(barcodeType);
|
||||
|
||||
assertEquals(false, activity.isFinishing());
|
||||
saveButton.performClick();
|
||||
assertEquals(true, activity.isFinishing());
|
||||
|
||||
assertEquals(1, db.getLoyaltyCardCount());
|
||||
|
||||
LoyaltyCard card = db.getLoyaltyCard(1);
|
||||
assertEquals(store, card.store);
|
||||
assertEquals(cardId, card.cardId);
|
||||
assertEquals(barcodeType, card.barcodeType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiate and complete a barcode capture, either in success
|
||||
* or in failure
|
||||
*/
|
||||
private void captureBarcodeWithResult(final Activity activity, final int buttonId, final boolean success) throws IOException
|
||||
{
|
||||
// Start image capture
|
||||
final Button captureButton = (Button) activity.findViewById(buttonId);
|
||||
captureButton.performClick();
|
||||
|
||||
ShadowActivity.IntentForResult intentForResult = shadowOf(activity).peekNextStartedActivityForResult();
|
||||
assertNotNull(intentForResult);
|
||||
|
||||
Intent intent = intentForResult.intent;
|
||||
assertNotNull(intent);
|
||||
|
||||
String action = intent.getAction();
|
||||
assertNotNull(action);
|
||||
assertEquals(Intents.Scan.ACTION, action);
|
||||
|
||||
Bundle bundle = intent.getExtras();
|
||||
assertNotNull(bundle);
|
||||
|
||||
Intent resultIntent = new Intent(intent);
|
||||
Bundle resultBuddle = new Bundle();
|
||||
resultBuddle.putString(Intents.Scan.RESULT, BARCODE_DATA);
|
||||
resultBuddle.putString(Intents.Scan.RESULT_FORMAT, BARCODE_TYPE);
|
||||
resultIntent.putExtras(resultBuddle);
|
||||
|
||||
// Respond to image capture, success
|
||||
shadowOf(activity).receiveResult(
|
||||
intent,
|
||||
success ? Activity.RESULT_OK : Activity.RESULT_CANCELED,
|
||||
resultIntent);
|
||||
}
|
||||
|
||||
private void checkFieldProperties(final Activity activity, final int id, final int visibility,
|
||||
final String contents)
|
||||
{
|
||||
final View view = activity.findViewById(id);
|
||||
assertNotNull(view);
|
||||
assertEquals(visibility, view.getVisibility());
|
||||
if(contents != null)
|
||||
{
|
||||
TextView textView = (TextView)view;
|
||||
assertEquals(contents, textView.getText().toString());
|
||||
}
|
||||
}
|
||||
|
||||
private void checkAllFields(final Activity activity, final String store, final String cardId,
|
||||
final String barcodeType)
|
||||
{
|
||||
int cardIdVisibility = cardId.isEmpty() ? View.GONE : View.VISIBLE;
|
||||
|
||||
checkFieldProperties(activity, R.id.storeName, View.VISIBLE, store);
|
||||
checkFieldProperties(activity, R.id.cardId, View.VISIBLE, cardId);
|
||||
checkFieldProperties(activity, R.id.barcodeType, View.VISIBLE, barcodeType);
|
||||
checkFieldProperties(activity, R.id.captureButton, View.VISIBLE, null);
|
||||
checkFieldProperties(activity, R.id.saveButton, View.VISIBLE, null);
|
||||
checkFieldProperties(activity, R.id.cancelButton, View.VISIBLE, null);
|
||||
checkFieldProperties(activity, R.id.barcode, View.VISIBLE, null);
|
||||
|
||||
checkFieldProperties(activity, R.id.barcodeIdLayout, cardIdVisibility, null);
|
||||
checkFieldProperties(activity, R.id.barcodeLayout, cardIdVisibility, null);
|
||||
checkFieldProperties(activity, R.id.barcodeTypeLayout, View.GONE, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startWithoutParametersCheckFieldsAvailable()
|
||||
{
|
||||
ActivityController activityController = Robolectric.buildActivity(LoyaltyCardViewActivity.class).create();
|
||||
activityController.start();
|
||||
activityController.visible();
|
||||
activityController.resume();
|
||||
|
||||
Activity activity = (Activity)activityController.get();
|
||||
|
||||
checkAllFields(activity, "", "", "");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startWithoutParametersCannotCreateGiftCard()
|
||||
{
|
||||
ActivityController activityController = Robolectric.buildActivity(LoyaltyCardViewActivity.class).create();
|
||||
activityController.start();
|
||||
activityController.visible();
|
||||
activityController.resume();
|
||||
|
||||
Activity activity = (Activity)activityController.get();
|
||||
DBHelper db = new DBHelper(activity);
|
||||
assertEquals(0, db.getLoyaltyCardCount());
|
||||
|
||||
final EditText storeField = (EditText) activity.findViewById(R.id.storeName);
|
||||
final EditText cardIdField = (EditText) activity.findViewById(R.id.cardId);
|
||||
|
||||
final Button saveButton = (Button) activity.findViewById(R.id.saveButton);
|
||||
|
||||
saveButton.performClick();
|
||||
assertEquals(0, db.getLoyaltyCardCount());
|
||||
|
||||
storeField.setText("store");
|
||||
saveButton.performClick();
|
||||
assertEquals(0, db.getLoyaltyCardCount());
|
||||
|
||||
cardIdField.setText("cardId");
|
||||
saveButton.performClick();
|
||||
assertEquals(0, db.getLoyaltyCardCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startWithoutParametersCancel()
|
||||
{
|
||||
ActivityController activityController = Robolectric.buildActivity(LoyaltyCardViewActivity.class).create();
|
||||
activityController.start();
|
||||
activityController.visible();
|
||||
activityController.resume();
|
||||
|
||||
Activity activity = (Activity)activityController.get();
|
||||
|
||||
final Button cancelButton = (Button) activity.findViewById(R.id.cancelButton);
|
||||
|
||||
assertEquals(false, activity.isFinishing());
|
||||
cancelButton.performClick();
|
||||
assertEquals(true, activity.isFinishing());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startWithoutParametersCaptureBarcodeCreateGiftCard() throws IOException
|
||||
{
|
||||
registerMediaStoreIntentHandler();
|
||||
|
||||
ActivityController activityController = Robolectric.buildActivity(LoyaltyCardViewActivity.class).create();
|
||||
activityController.start();
|
||||
activityController.visible();
|
||||
activityController.resume();
|
||||
|
||||
Activity activity = (Activity)activityController.get();
|
||||
|
||||
checkAllFields(activity, "", "", "");
|
||||
|
||||
// Complete barcode capture successfully
|
||||
captureBarcodeWithResult(activity, R.id.captureButton, true);
|
||||
|
||||
checkAllFields(activity, "", BARCODE_DATA, BARCODE_TYPE);
|
||||
|
||||
// Save and check the gift card
|
||||
saveLoyaltyCardWithArguments(activity, "store", BARCODE_DATA, BARCODE_TYPE, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startWithoutParametersCaptureBarcodeFailure() throws IOException
|
||||
{
|
||||
ActivityController activityController = Robolectric.buildActivity(LoyaltyCardViewActivity.class).create();
|
||||
activityController.start();
|
||||
activityController.visible();
|
||||
activityController.resume();
|
||||
|
||||
Activity activity = (Activity)activityController.get();
|
||||
|
||||
checkAllFields(activity, "", "", "");
|
||||
|
||||
// Complete barcode capture in failure
|
||||
captureBarcodeWithResult(activity, R.id.captureButton, false);
|
||||
|
||||
checkAllFields(activity, "", "", "");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startWithoutParametersCaptureBarcodeCancel() throws IOException
|
||||
{
|
||||
ActivityController activityController = Robolectric.buildActivity(LoyaltyCardViewActivity.class).create();
|
||||
activityController.start();
|
||||
activityController.visible();
|
||||
activityController.resume();
|
||||
|
||||
Activity activity = (Activity)activityController.get();
|
||||
|
||||
checkAllFields(activity, "", "", "");
|
||||
|
||||
// Complete barcode capture successfully
|
||||
captureBarcodeWithResult(activity, R.id.captureButton, true);
|
||||
|
||||
checkAllFields(activity, "", BARCODE_DATA, BARCODE_TYPE);
|
||||
|
||||
// Cancel the gift card creation
|
||||
final Button cancelButton = (Button) activity.findViewById(R.id.cancelButton);
|
||||
assertEquals(false, activity.isFinishing());
|
||||
cancelButton.performClick();
|
||||
assertEquals(true, activity.isFinishing());
|
||||
}
|
||||
|
||||
private ActivityController createActivityWithLoyaltyCard()
|
||||
{
|
||||
Intent intent = new Intent();
|
||||
final Bundle bundle = new Bundle();
|
||||
bundle.putInt("id", 1);
|
||||
bundle.putBoolean("update", true);
|
||||
intent.putExtras(bundle);
|
||||
|
||||
return Robolectric.buildActivity(LoyaltyCardViewActivity.class).withIntent(intent).create();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startWithGiftCardCheckDisplay() throws IOException
|
||||
{
|
||||
ActivityController activityController = createActivityWithLoyaltyCard();
|
||||
Activity activity = (Activity)activityController.get();
|
||||
DBHelper db = new DBHelper(activity);
|
||||
|
||||
db.insertLoyaltyCard("store", BARCODE_DATA, BARCODE_TYPE);
|
||||
|
||||
activityController.start();
|
||||
activityController.visible();
|
||||
activityController.resume();
|
||||
|
||||
checkAllFields(activity, "store", BARCODE_DATA, BARCODE_TYPE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startWithLoyaltyCardWithBarcodeUpdateBarcode() throws IOException
|
||||
{
|
||||
ActivityController activityController = createActivityWithLoyaltyCard();
|
||||
Activity activity = (Activity)activityController.get();
|
||||
DBHelper db = new DBHelper(activity);
|
||||
|
||||
db.insertLoyaltyCard("store", EAN_BARCODE_DATA, EAN_BARCODE_TYPE);
|
||||
|
||||
activityController.start();
|
||||
activityController.visible();
|
||||
activityController.resume();
|
||||
|
||||
checkAllFields(activity, "store", EAN_BARCODE_DATA, EAN_BARCODE_TYPE);
|
||||
|
||||
// Complete barcode capture successfully
|
||||
captureBarcodeWithResult(activity, R.id.captureButton, true);
|
||||
|
||||
checkAllFields(activity, "store", BARCODE_DATA, BARCODE_TYPE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startWithGiftCardWithReceiptUpdateReceiptCancel() throws IOException
|
||||
{
|
||||
ActivityController activityController = createActivityWithLoyaltyCard();
|
||||
Activity activity = (Activity)activityController.get();
|
||||
DBHelper db = new DBHelper(activity);
|
||||
|
||||
db.insertLoyaltyCard("store", EAN_BARCODE_DATA, EAN_BARCODE_TYPE);
|
||||
|
||||
activityController.start();
|
||||
activityController.visible();
|
||||
activityController.resume();
|
||||
|
||||
checkAllFields(activity, "store", EAN_BARCODE_DATA, EAN_BARCODE_TYPE);
|
||||
|
||||
// Complete barcode capture successfully
|
||||
captureBarcodeWithResult(activity, R.id.captureButton, true);
|
||||
|
||||
checkAllFields(activity, "store", BARCODE_DATA, BARCODE_TYPE);
|
||||
|
||||
// Cancel the gift card creation
|
||||
final Button cancelButton = (Button) activity.findViewById(R.id.cancelButton);
|
||||
assertEquals(false, activity.isFinishing());
|
||||
cancelButton.performClick();
|
||||
assertEquals(true, activity.isFinishing());
|
||||
}
|
||||
}
|
||||
101
app/src/test/java/protect/card_locker/MainActivityTest.java
Normal file
@@ -0,0 +1,101 @@
|
||||
package protect.card_locker;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.view.Menu;
|
||||
import android.view.View;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricGradleTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.util.ActivityController;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.robolectric.Shadows.shadowOf;
|
||||
|
||||
@RunWith(RobolectricGradleTestRunner.class)
|
||||
@Config(constants = BuildConfig.class, sdk = 17)
|
||||
public class MainActivityTest
|
||||
{
|
||||
@Test
|
||||
public void initiallyNoLoyaltyCards() throws Exception
|
||||
{
|
||||
Activity activity = Robolectric.setupActivity(MainActivity.class);
|
||||
assertTrue(activity != null);
|
||||
|
||||
TextView helpText = (TextView)activity.findViewById(R.id.helpText);
|
||||
assertEquals(View.VISIBLE, helpText.getVisibility());
|
||||
|
||||
ListView list = (ListView)activity.findViewById(R.id.list);
|
||||
assertEquals(View.GONE, list.getVisibility());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onCreateShouldInflateLayout() throws Exception
|
||||
{
|
||||
final MainActivity activity = Robolectric.setupActivity(MainActivity.class);
|
||||
|
||||
final Menu menu = shadowOf(activity).getOptionsMenu();
|
||||
assertTrue(menu != null);
|
||||
|
||||
// The settings and add button should be present
|
||||
assertEquals(menu.size(), 1);
|
||||
|
||||
assertEquals("Add", menu.findItem(R.id.action_add).getTitle().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clickAddLaunchesLoyaltyCardViewActivity()
|
||||
{
|
||||
final MainActivity activity = Robolectric.setupActivity(MainActivity.class);
|
||||
|
||||
shadowOf(activity).clickMenuItem(R.id.action_add);
|
||||
|
||||
Intent intent = shadowOf(activity).peekNextStartedActivityForResult().intent;
|
||||
|
||||
assertEquals(new ComponentName(activity, LoyaltyCardViewActivity.class), intent.getComponent());
|
||||
assertNull(intent.getExtras());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addOneLoyaltyCard()
|
||||
{
|
||||
ActivityController activityController = Robolectric.buildActivity(MainActivity.class).create();
|
||||
|
||||
Activity mainActivity = (Activity)activityController.get();
|
||||
activityController.start();
|
||||
activityController.resume();
|
||||
|
||||
TextView helpText = (TextView)mainActivity.findViewById(R.id.helpText);
|
||||
ListView list = (ListView)mainActivity.findViewById(R.id.list);
|
||||
|
||||
assertEquals(0, list.getCount());
|
||||
|
||||
DBHelper db = new DBHelper(mainActivity);
|
||||
db.insertLoyaltyCard("store", "cardId", BarcodeFormat.UPC_A.toString());
|
||||
|
||||
assertEquals(View.VISIBLE, helpText.getVisibility());
|
||||
assertEquals(View.GONE, list.getVisibility());
|
||||
|
||||
activityController.pause();
|
||||
activityController.resume();
|
||||
|
||||
assertEquals(View.GONE, helpText.getVisibility());
|
||||
assertEquals(View.VISIBLE, list.getVisibility());
|
||||
|
||||
assertEquals(1, list.getAdapter().getCount());
|
||||
Cursor cursor = (Cursor)list.getAdapter().getItem(0);
|
||||
assertNotNull(cursor);
|
||||
}
|
||||
}
|
||||
23
build.gradle
Normal file
@@ -0,0 +1,23 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:1.5.0'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
||||
18
gradle.properties
Normal file
@@ -0,0 +1,18 @@
|
||||
# Project-wide Gradle settings.
|
||||
|
||||
# IDE (e.g. Android Studio) users:
|
||||
# Gradle settings configured through the IDE *will override*
|
||||
# any settings specified in this file.
|
||||
|
||||
# For more details on how to configure your build environment visit
|
||||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||
|
||||
# Specifies the JVM arguments used for the daemon process.
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
# Default value: -Xmx10248m -XX:MaxPermSize=256m
|
||||
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
||||
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# This option should only be used with decoupled projects. More details, visit
|
||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
# org.gradle.parallel=true
|
||||
1
settings.gradle
Normal file
@@ -0,0 +1 @@
|
||||
include ':app'
|
||||