Compare commits
50 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5960f03f9b | ||
|
|
b1df0c0baf | ||
|
|
bfb131c811 | ||
|
|
4580ee8017 | ||
|
|
d76a6d79d7 | ||
|
|
b38e035fb6 | ||
|
|
eeb41376c5 | ||
|
|
89f649e5ef | ||
|
|
4bde8f49b1 | ||
|
|
87c1bbdbf4 | ||
|
|
7029818789 | ||
|
|
b64c29bf96 | ||
|
|
24317f4d99 | ||
|
|
b9d3699038 | ||
|
|
ed3c9ceb50 | ||
|
|
0a938628cb | ||
|
|
5720da1581 | ||
|
|
5393903872 | ||
|
|
8e0a4b978d | ||
|
|
df21c2577d | ||
|
|
a7d5b6fa0c | ||
|
|
b49501e66a | ||
|
|
65d0f57358 | ||
|
|
927ac61912 | ||
|
|
fd2b84f318 | ||
|
|
ed4afed538 | ||
|
|
007427023b | ||
|
|
b4ff68eddb | ||
|
|
151b81daa7 | ||
|
|
c090af1c7d | ||
|
|
54a0f89821 | ||
|
|
f01058d5b8 | ||
|
|
e01c77681b | ||
|
|
c49ecdca56 | ||
|
|
b7672e5247 | ||
|
|
71777a74fd | ||
|
|
bebab039d7 | ||
|
|
588a573878 | ||
|
|
a9bbf8fb65 | ||
|
|
175135d695 | ||
|
|
9f08d07a6a | ||
|
|
07f50b1544 | ||
|
|
584064a4a2 | ||
|
|
484f357a82 | ||
|
|
e32b40a024 | ||
|
|
010b88d477 | ||
|
|
fe0bb7b870 | ||
|
|
925f780599 | ||
|
|
9492d206d9 | ||
|
|
a32415b4d2 |
@@ -1,4 +1,5 @@
|
||||
language: android
|
||||
sudo: true
|
||||
android:
|
||||
components:
|
||||
# Uncomment the lines below if you want to
|
||||
|
||||
69
CHANGELOG.md
Normal file
@@ -0,0 +1,69 @@
|
||||
## v0.8 (2016-11-22)
|
||||
|
||||
New features/improvements:
|
||||
- Screen brightness increased to its maximum when displaying a card, to help barcode scanners successfully capture the barcode. (https://github.com/brarcher/loyalty-card-locker/pull/54)
|
||||
- Add a delete confirmation when deleting a card. (https://github.com/brarcher/loyalty-card-locker/pull/55)
|
||||
- Add translations for German (https://github.com/brarcher/loyalty-card-locker/pull/57) and Czech (https://github.com/brarcher/loyalty-card-locker/pull/58).
|
||||
- Clarification change for Italian translation. (https://github.com/brarcher/loyalty-card-locker/pull/66)
|
||||
|
||||
## v0.7 (2016-07-14)
|
||||
|
||||
New features/improvements:
|
||||
- Long-click of a card brings up option to copy card ID to the clipboard. (https://github.com/brarcher/loyalty-card-locker/issues/49)
|
||||
|
||||
Bug fixes:
|
||||
- Back button on Input/Export view now works, moving user to main view
|
||||
|
||||
## v0.6 (2016-05-23)
|
||||
|
||||
New features/improvements:
|
||||
- Allow user to enter barcode manually. If a user elects to enter a barcode manually, a list of all valid and supported barcode images is displayed. The user then may select the barcode image which matches what the user wants. https://github.com/brarcher/loyalty-card-locker/issues/33, https://github.com/brarcher/loyalty-card-locker/pull/44
|
||||
|
||||
Bug fixes:
|
||||
- Resolve issue where some displayed barcodes were blurry. (https://github.com/brarcher/loyalty-card-locker/issues/37)
|
||||
|
||||
## v0.5 (2016-05-16)
|
||||
|
||||
New features/improvements:
|
||||
- An about dialog can be opened from the main screen, which gives details about the application and project on GitHub (https://github.com/brarcher/loyalty-card-locker/issues/19)
|
||||
- Allow loyalty card information to be imported from/exported to a CSV file in external storage (https://github.com/brarcher/loyalty-card-locker/issues/36 https://github.com/brarcher/loyalty-card-locker/issues/20)
|
||||
|
||||
## v0.4 (2016-04-09)
|
||||
|
||||
New features/improvements:
|
||||
- Dutch translation
|
||||
- Allow name field to be editable after adding loyalty card
|
||||
- Add an optional note field
|
||||
|
||||
Bug fixes:
|
||||
|
||||
- Resolve all issues identified by FindBugs and require all FindBugs issues be resolved prior to pull request acceptance
|
||||
|
||||
## v0.3 (2016-02-11)
|
||||
|
||||
- Now officially supports the following list of 1D and 2D barcodes:
|
||||
* AZTEC
|
||||
* CODABAR
|
||||
* CODE_39
|
||||
* CODE_128
|
||||
* DATA_MATRIX
|
||||
* EAN_8
|
||||
* EAN_13
|
||||
* ITF
|
||||
* PDF_417
|
||||
* QR_CODE
|
||||
* UPC_A
|
||||
- Generated barcodes are larger, easier to scan from a scanning device
|
||||
|
||||
## v0.2 (2016-02-07)
|
||||
|
||||
- Italian translations
|
||||
- Support for all 1D barcode types. (Originally only product 1D barcodes were supported)
|
||||
- Add required camera permission, which was initially missing.
|
||||
|
||||
|
||||
## v0.1 (2016-01-30)
|
||||
|
||||
- Ability to create/edit/delete loyalty cards
|
||||
- Capture barcode of loyalty card using a camera
|
||||
- Display captured barcode, for scanning at a store
|
||||
12
README.md
@@ -1,7 +1,7 @@
|
||||
# Loyalty Card Locker
|
||||
# Loyalty Card Keychain
|
||||
[](https://travis-ci.org/brarcher/loyalty-card-locker)
|
||||
|
||||
[](https://f-droid.org/repository/browse/?fdid=protect.card_locker "Loyalty Card Locker on F-Droid")
|
||||
[](https://f-droid.org/repository/browse/?fdid=protect.card_locker "Loyalty Card Keychain on F-Droid")
|
||||
|
||||
|
||||
Stores all of your store loyalty cards on your phone, removing the need to carry them around. Currently the following barcode types are supported:
|
||||
@@ -21,6 +21,14 @@ Stores all of your store loyalty cards on your phone, removing the need to carry
|
||||
If there is any interest in improving this project, kindly submit a pull request with
|
||||
proposed changes.
|
||||
|
||||
# Screenshots
|
||||
|
||||
[<img src="https://cloud.githubusercontent.com/assets/5264535/18036233/32fae9a6-6d33-11e6-81e4-55ba60e83d9b.png" width=250>](https://cloud.githubusercontent.com/assets/5264535/18036233/32fae9a6-6d33-11e6-81e4-55ba60e83d9b.png)
|
||||
[<img src="https://cloud.githubusercontent.com/assets/5264535/18036246/7ee5c7f0-6d33-11e6-90cf-d2b3ca5a94c7.png" width=250>](https://cloud.githubusercontent.com/assets/5264535/18036246/7ee5c7f0-6d33-11e6-90cf-d2b3ca5a94c7.png)
|
||||
|
||||
[<img src="https://cloud.githubusercontent.com/assets/5264535/18036258/bb19562e-6d33-11e6-856e-740e8785ad71.png" width=250>](https://cloud.githubusercontent.com/assets/5264535/18036258/bb19562e-6d33-11e6-856e-740e8785ad71.png)
|
||||
[<img src="https://cloud.githubusercontent.com/assets/5264535/18036269/0202baf8-6d34-11e6-9c17-449d5b348738.png" width=250>](https://cloud.githubusercontent.com/assets/5264535/18036269/0202baf8-6d34-11e6-9c17-449d5b348738.png)
|
||||
|
||||
# Building
|
||||
|
||||
To build, use the gradle wrapper scripts provided in the top level directory of the project. The following will
|
||||
|
||||
@@ -14,8 +14,8 @@ android {
|
||||
applicationId "protect.card_locker"
|
||||
minSdkVersion 11
|
||||
targetSdkVersion 23
|
||||
versionCode 7
|
||||
versionName "0.7"
|
||||
versionCode 9
|
||||
versionName "0.9"
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
|
||||
@@ -1,25 +1,42 @@
|
||||
package protect.card_locker;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.Log;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
public class ImportExportActivity extends AppCompatActivity
|
||||
{
|
||||
private static final int PERMISSIONS_EXTERNAL_STORAGE_IMPORT = 1;
|
||||
private static final int PERMISSIONS_EXTERNAL_STORAGE_EXPORT = 2;
|
||||
private static final String TAG = "LoyaltyCardLocker";
|
||||
|
||||
ImportExportTask importExporter;
|
||||
private static final int PERMISSIONS_EXTERNAL_STORAGE = 1;
|
||||
private static final int CHOOSE_EXPORT_FILE = 2;
|
||||
|
||||
private ImportExportTask importExporter;
|
||||
|
||||
private final File sdcardDir = Environment.getExternalStorageDirectory();
|
||||
private final File exportFile = new File(sdcardDir, "LoyaltyCardLocker.csv");
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
@@ -34,25 +51,20 @@ public class ImportExportActivity extends AppCompatActivity
|
||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
|
||||
Button importButton = (Button)findViewById(R.id.importButton);
|
||||
importButton.setOnClickListener(new View.OnClickListener()
|
||||
// If the application does not have permissions to external
|
||||
// storage, as for it now
|
||||
|
||||
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)
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
if (ContextCompat.checkSelfPermission(ImportExportActivity.this,
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)
|
||||
{
|
||||
startImport();
|
||||
}
|
||||
else
|
||||
{
|
||||
ActivityCompat.requestPermissions(ImportExportActivity.this,
|
||||
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
|
||||
PERMISSIONS_EXTERNAL_STORAGE_IMPORT);
|
||||
}
|
||||
}
|
||||
});
|
||||
ActivityCompat.requestPermissions(ImportExportActivity.this,
|
||||
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE},
|
||||
PERMISSIONS_EXTERNAL_STORAGE);
|
||||
}
|
||||
|
||||
|
||||
Button exportButton = (Button)findViewById(R.id.exportButton);
|
||||
exportButton.setOnClickListener(new View.OnClickListener()
|
||||
@@ -60,56 +72,120 @@ public class ImportExportActivity extends AppCompatActivity
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
if (ContextCompat.checkSelfPermission(ImportExportActivity.this,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)
|
||||
{
|
||||
startExport();
|
||||
}
|
||||
else
|
||||
{
|
||||
ActivityCompat.requestPermissions(ImportExportActivity.this,
|
||||
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
|
||||
PERMISSIONS_EXTERNAL_STORAGE_EXPORT);
|
||||
}
|
||||
startExport();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Check that there is an activity that can bring up a file chooser
|
||||
final Intent intentPickAction = new Intent(Intent.ACTION_PICK);
|
||||
intentPickAction.setData(Uri.parse("file://"));
|
||||
|
||||
Button importFilesystem = (Button) findViewById(R.id.importOptionFilesystemButton);
|
||||
importFilesystem.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
chooseFileWithIntent(intentPickAction);
|
||||
}
|
||||
});
|
||||
|
||||
if(isCallable(getApplicationContext(), intentPickAction) == false)
|
||||
{
|
||||
findViewById(R.id.dividerImportFilesystem).setVisibility(View.GONE);
|
||||
findViewById(R.id.importOptionFilesystemTitle).setVisibility(View.GONE);
|
||||
findViewById(R.id.importOptionFilesystemExplanation).setVisibility(View.GONE);
|
||||
importFilesystem.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
|
||||
// Check that there is an application that can find content
|
||||
final Intent intentGetContentAction = new Intent(Intent.ACTION_GET_CONTENT);
|
||||
intentGetContentAction.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
intentGetContentAction.setType("*/*");
|
||||
|
||||
Button importApplication = (Button) findViewById(R.id.importOptionApplicationButton);
|
||||
importApplication.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
chooseFileWithIntent(intentGetContentAction);
|
||||
}
|
||||
});
|
||||
|
||||
if(isCallable(getApplicationContext(), intentGetContentAction) == false)
|
||||
{
|
||||
findViewById(R.id.dividerImportApplication).setVisibility(View.GONE);
|
||||
findViewById(R.id.importOptionApplicationTitle).setVisibility(View.GONE);
|
||||
findViewById(R.id.importOptionApplicationExplanation).setVisibility(View.GONE);
|
||||
importApplication.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
|
||||
// This option, to import from the fixed location, should always be present
|
||||
|
||||
Button importButton = (Button)findViewById(R.id.importOptionFixedButton);
|
||||
importButton.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
startImport(exportFile);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void startImport()
|
||||
private void startImport(File target)
|
||||
{
|
||||
ImportExportTask.TaskCompleteListener listener = new ImportExportTask.TaskCompleteListener()
|
||||
{
|
||||
@Override
|
||||
public void onTaskComplete(boolean success, File file)
|
||||
{
|
||||
onImportComplete(success, file);
|
||||
}
|
||||
};
|
||||
|
||||
importExporter = new ImportExportTask(ImportExportActivity.this,
|
||||
true, DataFormat.CSV);
|
||||
true, DataFormat.CSV, target, listener);
|
||||
importExporter.execute();
|
||||
}
|
||||
|
||||
private void startExport()
|
||||
{
|
||||
ImportExportTask.TaskCompleteListener listener = new ImportExportTask.TaskCompleteListener()
|
||||
{
|
||||
@Override
|
||||
public void onTaskComplete(boolean success, File file)
|
||||
{
|
||||
onExportComplete(success, file);
|
||||
}
|
||||
};
|
||||
|
||||
importExporter = new ImportExportTask(ImportExportActivity.this,
|
||||
false, DataFormat.CSV);
|
||||
false, DataFormat.CSV, exportFile, listener);
|
||||
importExporter.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults)
|
||||
{
|
||||
if(requestCode == PERMISSIONS_EXTERNAL_STORAGE_IMPORT ||
|
||||
requestCode == PERMISSIONS_EXTERNAL_STORAGE_EXPORT)
|
||||
if(requestCode == PERMISSIONS_EXTERNAL_STORAGE)
|
||||
{
|
||||
// If request is cancelled, the result arrays are empty.
|
||||
if (grantResults.length > 0 &&
|
||||
grantResults[0] == PackageManager.PERMISSION_GRANTED)
|
||||
boolean success = grantResults.length > 0;
|
||||
|
||||
for(int grant : grantResults)
|
||||
{
|
||||
// permission was granted.
|
||||
if(requestCode == PERMISSIONS_EXTERNAL_STORAGE_IMPORT)
|
||||
if(grant != PackageManager.PERMISSION_GRANTED)
|
||||
{
|
||||
startImport();
|
||||
}
|
||||
else
|
||||
{
|
||||
startExport();
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
if(success == false)
|
||||
{
|
||||
// External storage permission rejected, inform user that
|
||||
// import/export is prevented
|
||||
@@ -143,4 +219,159 @@ public class ImportExportActivity extends AppCompatActivity
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private void onImportComplete(boolean success, File path)
|
||||
{
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
|
||||
if(success)
|
||||
{
|
||||
builder.setTitle(R.string.importSuccessfulTitle);
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.setTitle(R.string.importFailedTitle);
|
||||
}
|
||||
|
||||
int messageId = success ? R.string.importedFrom : R.string.importFailed;
|
||||
|
||||
final String template = getResources().getString(messageId);
|
||||
final String message = String.format(template, path.getAbsolutePath());
|
||||
builder.setMessage(message);
|
||||
builder.setNeutralButton(R.string.ok, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
|
||||
builder.create().show();
|
||||
}
|
||||
|
||||
private void onExportComplete(boolean success, final File path)
|
||||
{
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
|
||||
if(success)
|
||||
{
|
||||
builder.setTitle(R.string.exportSuccessfulTitle);
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.setTitle(R.string.exportFailedTitle);
|
||||
}
|
||||
|
||||
int messageId = success ? R.string.exportedTo : R.string.exportFailed;
|
||||
|
||||
final String template = getResources().getString(messageId);
|
||||
final String message = String.format(template, path.getAbsolutePath());
|
||||
builder.setMessage(message);
|
||||
builder.setNeutralButton(R.string.ok, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
|
||||
if(success)
|
||||
{
|
||||
final CharSequence sendLabel = ImportExportActivity.this.getResources().getText(R.string.sendLabel);
|
||||
|
||||
builder.setPositiveButton(sendLabel, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
Uri outputUri = Uri.fromFile(path);
|
||||
Intent sendIntent = new Intent(Intent.ACTION_SEND);
|
||||
sendIntent.putExtra(Intent.EXTRA_STREAM, outputUri);
|
||||
sendIntent.setType("text/plain");
|
||||
|
||||
ImportExportActivity.this.startActivity(Intent.createChooser(sendIntent,
|
||||
sendLabel));
|
||||
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
builder.create().show();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if there is at least one activity that can perform the given intent
|
||||
*/
|
||||
private boolean isCallable(Context context, final Intent intent)
|
||||
{
|
||||
PackageManager manager = context.getPackageManager();
|
||||
if(manager == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
List<ResolveInfo> list = manager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
|
||||
|
||||
for(ResolveInfo info : list)
|
||||
{
|
||||
if(info.activityInfo.exported)
|
||||
{
|
||||
// There is one activity which is available to be called
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void chooseFileWithIntent(Intent intent)
|
||||
{
|
||||
try
|
||||
{
|
||||
startActivityForResult(intent, CHOOSE_EXPORT_FILE);
|
||||
}
|
||||
catch (ActivityNotFoundException e)
|
||||
{
|
||||
Log.e(TAG, "No activity found to handle intent", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data)
|
||||
{
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
|
||||
if (resultCode == RESULT_OK && requestCode == CHOOSE_EXPORT_FILE)
|
||||
{
|
||||
String path = null;
|
||||
|
||||
Uri uri = data.getData();
|
||||
if(uri != null && uri.toString().startsWith("/"))
|
||||
{
|
||||
uri = Uri.parse("file://" + uri.toString());
|
||||
}
|
||||
|
||||
if(uri != null)
|
||||
{
|
||||
path = uri.getPath();
|
||||
}
|
||||
|
||||
if(path != null)
|
||||
{
|
||||
Log.e(TAG, "Starting file import with: " + uri.toString());
|
||||
startImport(new File(path));
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.e(TAG, "Fail to make sense of URI returned from activity: " + (uri != null ? uri.toString() : "null"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.w(TAG, "Failed onActivityResult(), result=" + resultCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,49 +16,31 @@ import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
class ImportExportTask extends AsyncTask<Void, Void, Void>
|
||||
class ImportExportTask extends AsyncTask<Void, Void, Boolean>
|
||||
{
|
||||
private static final String TAG = "BudgetWatch";
|
||||
|
||||
private static final String TARGET_FILE = "LoyaltyCardLocker.csv";
|
||||
private static final String TAG = "LoyaltyCardLocker";
|
||||
|
||||
private Activity activity;
|
||||
private boolean doImport;
|
||||
private DataFormat format;
|
||||
private File target;
|
||||
private TaskCompleteListener listener;
|
||||
|
||||
private ProgressDialog progress;
|
||||
|
||||
public ImportExportTask(Activity activity, boolean doImport, DataFormat format)
|
||||
public ImportExportTask(Activity activity, boolean doImport, DataFormat format, File target,
|
||||
TaskCompleteListener listener)
|
||||
{
|
||||
super();
|
||||
this.activity = activity;
|
||||
this.doImport = doImport;
|
||||
this.format = format;
|
||||
this.target = target;
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
private void toastWithArg(int stringId, String argument)
|
||||
private boolean performImport(File importFile, DBHelper db)
|
||||
{
|
||||
final String template = activity.getResources().getString(stringId);
|
||||
final String message = String.format(template, argument);
|
||||
|
||||
activity.runOnUiThread(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
Toast.makeText(activity, message, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void performImport(File importFile, DBHelper db)
|
||||
{
|
||||
if(importFile.exists() == false)
|
||||
{
|
||||
toastWithArg(R.string.fileMissing, importFile.getAbsolutePath());
|
||||
return;
|
||||
}
|
||||
|
||||
boolean result = false;
|
||||
|
||||
try
|
||||
@@ -73,11 +55,12 @@ class ImportExportTask extends AsyncTask<Void, Void, Void>
|
||||
Log.e(TAG, "Unable to import file", e);
|
||||
}
|
||||
|
||||
int messageId = result ? R.string.importedFrom : R.string.importFailed;
|
||||
toastWithArg(messageId, importFile.getAbsolutePath());
|
||||
Log.i(TAG, "Import of '" + importFile.getAbsolutePath() + "' result: " + result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void performExport(File exportFile, DBHelper db)
|
||||
private boolean performExport(File exportFile, DBHelper db)
|
||||
{
|
||||
boolean result = false;
|
||||
|
||||
@@ -93,8 +76,7 @@ class ImportExportTask extends AsyncTask<Void, Void, Void>
|
||||
Log.e(TAG, "Unable to export file", e);
|
||||
}
|
||||
|
||||
int messageId = result ? R.string.exportedTo : R.string.exportFailed;
|
||||
toastWithArg(messageId, exportFile.getAbsolutePath());
|
||||
return result;
|
||||
}
|
||||
|
||||
protected void onPreExecute()
|
||||
@@ -114,26 +96,27 @@ class ImportExportTask extends AsyncTask<Void, Void, Void>
|
||||
progress.show();
|
||||
}
|
||||
|
||||
protected Void doInBackground(Void... nothing)
|
||||
protected Boolean doInBackground(Void... nothing)
|
||||
{
|
||||
final File sdcardDir = Environment.getExternalStorageDirectory();
|
||||
final File importExportFile = new File(sdcardDir, TARGET_FILE);
|
||||
final DBHelper db = new DBHelper(activity);
|
||||
boolean result;
|
||||
|
||||
if(doImport)
|
||||
{
|
||||
performImport(importExportFile, db);
|
||||
result = performImport(target, db);
|
||||
}
|
||||
else
|
||||
{
|
||||
performExport(importExportFile, db);
|
||||
result = performExport(target, db);
|
||||
}
|
||||
|
||||
return null;
|
||||
return result;
|
||||
}
|
||||
|
||||
protected void onPostExecute(Void result)
|
||||
protected void onPostExecute(Boolean result)
|
||||
{
|
||||
listener.onTaskComplete(result, target);
|
||||
|
||||
progress.dismiss();
|
||||
Log.i(TAG, (doImport ? "Import" : "Export") + " Complete");
|
||||
}
|
||||
@@ -143,4 +126,9 @@ class ImportExportTask extends AsyncTask<Void, Void, Void>
|
||||
progress.dismiss();
|
||||
Log.i(TAG, (doImport ? "Import" : "Export") + " Cancelled");
|
||||
}
|
||||
|
||||
interface TaskCompleteListener
|
||||
{
|
||||
void onTaskComplete(boolean success, File file);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,13 @@ package protect.card_locker;
|
||||
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.Log;
|
||||
@@ -14,6 +16,8 @@ import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
@@ -56,6 +60,20 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
|
||||
Log.i(TAG, "To view card: " + loyaltyCardId);
|
||||
|
||||
if(viewLoyaltyCard)
|
||||
{
|
||||
// The brightness value is on a scale from [0, ..., 1], where
|
||||
// '1' is the brightest. We attempt to maximize the brightness
|
||||
// to help barcode readers scan the barcode.
|
||||
Window window = getWindow();
|
||||
if(window != null)
|
||||
{
|
||||
WindowManager.LayoutParams attributes = window.getAttributes();
|
||||
attributes.screenBrightness = 1F;
|
||||
window.setAttributes(attributes);
|
||||
}
|
||||
}
|
||||
|
||||
final EditText storeField = (EditText) findViewById(R.id.storeName);
|
||||
final EditText noteField = (EditText) findViewById(R.id.note);
|
||||
final EditText cardIdField = (EditText) findViewById(R.id.cardId);
|
||||
@@ -275,11 +293,33 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
break;
|
||||
|
||||
case R.id.action_delete:
|
||||
Log.e(TAG, "Deleting card: " + loyaltyCardId);
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setTitle(R.string.deleteTitle);
|
||||
builder.setMessage(R.string.deleteConfirmation);
|
||||
builder.setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
Log.e(TAG, "Deleting card: " + loyaltyCardId);
|
||||
|
||||
DBHelper db = new DBHelper(LoyaltyCardViewActivity.this);
|
||||
db.deleteLoyaltyCard(loyaltyCardId);
|
||||
finish();
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
AlertDialog dialog = builder.create();
|
||||
dialog.show();
|
||||
|
||||
DBHelper db = new DBHelper(this);
|
||||
db.deleteLoyaltyCard(loyaltyCardId);
|
||||
finish();
|
||||
return true;
|
||||
case R.id.action_edit:
|
||||
Intent intent = new Intent(getApplicationContext(), LoyaltyCardViewActivity.class);
|
||||
|
||||
@@ -19,36 +19,149 @@
|
||||
|
||||
</android.support.design.widget.AppBarLayout>
|
||||
|
||||
<LinearLayout android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="20dp"
|
||||
android:textSize="20sp"
|
||||
android:layout_gravity="center"
|
||||
android:text="@string/importExportHelp"/>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fillViewport="true"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||
|
||||
<LinearLayout android:orientation="horizontal"
|
||||
<LinearLayout android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
<Button
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingBottom="8dp">
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/importName"
|
||||
android:layout_weight="1.0"
|
||||
android:id="@+id/importButton"/>
|
||||
<Button
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/exportName"
|
||||
android:layout_weight="1.0"
|
||||
android:id="@+id/exportButton"/>
|
||||
</LinearLayout>
|
||||
android:textSize="@dimen/text_size_medium"
|
||||
android:layout_gravity="center"
|
||||
android:text="@string/importExportHelp"/>
|
||||
|
||||
</LinearLayout>
|
||||
<View
|
||||
android:id="@+id/dividerExport"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_margin="16dp"
|
||||
android:background="?android:attr/listDivider"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/exportOptionTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="@dimen/text_size_large"
|
||||
android:text="@string/exportName"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/exportOptionExplanation"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:textSize="@dimen/text_size_medium"
|
||||
android:text="@string/exportOptionExplanation"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/exportButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/exportName" />
|
||||
|
||||
<View
|
||||
android:id="@+id/dividerImportFilesystem"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_margin="16dp"
|
||||
android:background="?android:attr/listDivider"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/importOptionFilesystemTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="@dimen/text_size_large"
|
||||
android:text="@string/importOptionFilesystemTitle"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/importOptionFilesystemExplanation"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:textSize="@dimen/text_size_medium"
|
||||
android:text="@string/importOptionFilesystemExplanation"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/importOptionFilesystemButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/importOptionFilesystemButton" />
|
||||
|
||||
|
||||
<View
|
||||
android:id="@+id/dividerImportApplication"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_margin="16dp"
|
||||
android:background="?android:attr/listDivider"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/importOptionApplicationTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="@dimen/text_size_large"
|
||||
android:text="@string/importOptionApplicationTitle"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/importOptionApplicationExplanation"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:textSize="@dimen/text_size_medium"
|
||||
android:text="@string/importOptionApplicationExplanation"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/importOptionApplicationButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="Use external application" />
|
||||
|
||||
|
||||
<View
|
||||
android:id="@+id/dividerImportFixed"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_margin="16dp"
|
||||
android:background="?android:attr/listDivider"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/importOptionFixedTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="@dimen/text_size_large"
|
||||
android:text="@string/importOptionFixedTitle"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/importOptionFixedExplanation"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:textSize="@dimen/text_size_medium"
|
||||
android:text="@string/importOptionFixedExplanation"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/importOptionFixedButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/importOptionFixedButton" />
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
|
||||
|
||||
</android.support.design.widget.CoordinatorLayout>
|
||||
|
||||
|
Before Width: | Height: | Size: 1012 B After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 676 B After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 5.6 KiB |
78
app/src/main/res/values-cs/strings.xml
Normal file
@@ -0,0 +1,78 @@
|
||||
<resources
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
|
||||
<string name="app_name">Loyalty Card Keychain</string>
|
||||
<string name="action_add">Přidat</string>
|
||||
|
||||
<string name="noGiftCards">ZAtím némáte žádné věrnostní karty. Klikněte na tlačítko "+" (plus) nahoře a začněte.\n\nLoyalty Card Locker umožňuje nosit své věrnostní karty v telefonu, takže jsou vždy na dosah.</string>
|
||||
|
||||
<string name="storeName">Obchod</string>
|
||||
<string name="note">Poznámka</string>
|
||||
<string name="cardId">ID karty</string>
|
||||
<string name="barcodeType">Typ čárového kódu</string>
|
||||
|
||||
<string name="cancel">Zrušit</string>
|
||||
<string name="save">Uložit</string>
|
||||
<string name="capture">Naskenovat kartu</string>
|
||||
<string name="enterCard">Vložit vlastnoručně</string>
|
||||
<string name="edit">Editovat</string>
|
||||
<string name="delete">Smazat</string>
|
||||
<string name="confirm">Potvrdit</string>
|
||||
<string name="deleteTitle">Odstzranit věrnostní kartu</string>
|
||||
<string name="deleteConfirmation">Opravdu chcete smazat tuto věrnostní kartu?</string>
|
||||
<string name="ok">Ano</string>
|
||||
<string name="copy_to_clipboard">Kopírovat ID do schránky</string>
|
||||
|
||||
<string name="editCardTitle">Editovat věrnostní kartu</string>
|
||||
<string name="addCardTitle">Přidat věrnostní kartu</string>
|
||||
<string name="viewCardTitle">Zobrazit věrnostní kartu</string>
|
||||
<string name="scanCardBarcode">Oskenujte kód karty</string>
|
||||
|
||||
<string name="barcodeImageDescription">Obrázek kódu karty</string>
|
||||
|
||||
<string name="noStoreError">Nebyl zadán Obchod</string>
|
||||
<string name="noCardIdError">Nebylo zadáno ID karty</string>
|
||||
|
||||
<string name="cardIdFormat">%1$s: %2$s</string>
|
||||
|
||||
<string name="importExport">Import/Export</string>
|
||||
<string name="importName">Import</string>
|
||||
<string name="exportName">Export</string>
|
||||
<string name="importedFrom">Importováno z: %1$s</string>
|
||||
<string name="exportedTo">Exportováno do: %1$s</string>
|
||||
<string name="fileMissing">Doubor chybí: %1$s</string>
|
||||
<string name="importFailed">Import selhal: %1$s</string>
|
||||
<string name="exportFailed">Export selhal: %1$s</string>
|
||||
<string name="importing">Importuji…</string>
|
||||
<string name="exporting">Exportuji…</string>
|
||||
<string name="noExternalStoragePermissionError">Nelze importovat nebo exportovat karty bez přístupu k externímu uložišti</string>
|
||||
|
||||
<string name="about">O aplikaci</string>
|
||||
<string name="app_copyright_fmt">Copyright 2016-<xliff:g>%s</xliff:g> Branden Archer</string>
|
||||
<string name="app_license">Licensed under the GPLv3.</string>
|
||||
<string name="about_title_fmt">O aplikaci <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="debug_version_fmt">Verze: <xliff:g id="version">%s</xliff:g></string>
|
||||
<string name="app_revision_fmt">Revizní informace: <xliff:g id="app_revision_url">%s</xliff:g></string>
|
||||
<string name="app_libraries"><xliff:g id="app_name">%s</xliff:g> používá tyto knihovny třetích stran: <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
|
||||
<string name="selectBarcodeTitle">Vyberte čárový kód</string>
|
||||
<string name="enterBarcodeInstructions">Zadejte hodnotu čárového kódu a potm vyberte kód, který představuje čárový kód, který je na kartě.</string>
|
||||
|
||||
<string name="copy_to_clipboard_toast">ID karty zkopírováno do schránky</string>
|
||||
<string name="importExportHelp">Zálohování dat vám umožní přesunout vaše uložené karty na jiné zařízení.</string>
|
||||
<string name="importSuccessfulTitle">Import proběhl úspěšně</string>
|
||||
<string name="importFailedTitle">Import selhal</string>
|
||||
<string name="exportSuccessfulTitle">Export proběhl úspěšně</string>
|
||||
<string name="exportFailedTitle">Export selhal</string>
|
||||
<string name="exportOptionExplanation">Data jsou zapsána do kořenové složky externího uložiště.</string>
|
||||
<string name="importOptionFilesystemTitle">Import ze souborového systému</string>
|
||||
<string name="importOptionFilesystemExplanation">Vyberte konkrétní soubor v uložišti.</string>
|
||||
<string name="importOptionFilesystemButton">Ze souborového systému</string>
|
||||
<string name="importOptionApplicationTitle">Import ze souborového systému</string>
|
||||
<string name="importOptionApplicationExplanation">K otevření souboru použije externí aplikaci jako Dropbox, Google Drive, nebo vámi preferovaný prohlížeč souborů.</string>
|
||||
<string name="importOptionApplicationButton">Použít externí aplikaci</string>
|
||||
<string name="importOptionFixedTitle">Import z umístění exportu</string>
|
||||
<string name="importOptionFixedExplanation">Import ze stejné složky souborového systému do níž se zapisuje při exportu.</string>
|
||||
<string name="importOptionFixedButton">Použít složku exportu</string>
|
||||
<string name="sendLabel">Odeslat…</string>
|
||||
</resources>
|
||||
68
app/src/main/res/values-de/strings.xml
Normal file
@@ -0,0 +1,68 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="app_name">Loyalty Card Keychain</string>
|
||||
<string name="about">Über</string>
|
||||
<string name="about_title_fmt">Über <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="action_add">Neu</string>
|
||||
<string name="addCardTitle">Neue Kundenkarte</string>
|
||||
<string name="app_copyright_fmt">Copyright 2016-<xliff:g>%s</xliff:g> Branden Archer</string>
|
||||
<string name="app_license">Lizensiert unter der GPLv3.</string>
|
||||
<string name="app_libraries"><xliff:g id="app_name">%s</xliff:g> benutzt die folgenden Fremdbibliotheken: <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="viewCardTitle">Kundenkarte anzeigen</string>
|
||||
<string name="ok">Ok</string>
|
||||
<string name="note">Notiz</string>
|
||||
<string name="save">Speichern</string>
|
||||
<string name="scanCardBarcode">Barcode scannen</string>
|
||||
<string name="selectBarcodeTitle">Barcode auswählen</string>
|
||||
<string name="storeName">Firma</string>
|
||||
<string name="noStoreError">Keine Firma angegeben</string>
|
||||
<string name="exportName">Exportieren</string>
|
||||
<string name="exportedTo">Exportiert nach: %1$s</string>
|
||||
<string name="fileMissing">Datei fehlt: %1$s</string>
|
||||
<string name="importExport">Import/Export</string>
|
||||
<string name="importFailed">Import fehlgeschlagen: %1$s</string>
|
||||
<string name="importName">Import</string>
|
||||
<string name="importedFrom">Importiert von: %1$s</string>
|
||||
<string name="noCardIdError">Keine Kartennummer angegeben</string>
|
||||
<string name="noExternalStoragePermissionError">Ohne die Berechtigung für den externen Speicher kann kein Import oder Export erfolgen.</string>
|
||||
<string name="noGiftCards">Du hast noch keine Kundenkarte angelegt. Über den "+" Button oben rechts, kannst du welche anlegen.\n\nDiese App ermöglicht es dir, deine Kundenkarten immer mit dir zu führen.</string>
|
||||
<string name="cancel">Abrechen</string>
|
||||
<string name="capture">Karte aufnehmen</string>
|
||||
<string name="cardId">Kartennummer</string>
|
||||
<string name="cardIdFormat">%1$s: %2$s</string>
|
||||
<string name="confirm">Bestätigen</string>
|
||||
<string name="copy_to_clipboard">Kopiere die Nummer in die Zwischenablage</string>
|
||||
<string name="delete">Löschen</string>
|
||||
<string name="deleteConfirmation">Bitte bestätige, dass du die Karte löschen möchtest.</string>
|
||||
<string name="deleteTitle">Lösche die Kundenkarte</string>
|
||||
<string name="edit">Bearbeiten</string>
|
||||
<string name="editCardTitle">Kundenkarte bearbeiten</string>
|
||||
<string name="enterCard">Karte einfügen</string>
|
||||
<string name="exportFailed">Export fehlgeschlagen: %1$s</string>
|
||||
<string name="barcodeType">Barcodeart</string>
|
||||
<string name="barcodeImageDescription">Bild des Barcodes</string>
|
||||
<string name="copy_to_clipboard_toast">Nummer in die Zwischenablage kopiert</string>
|
||||
<string name="debug_version_fmt">Version: <xliff:g id="version">%s</xliff:g></string>
|
||||
<string name="enterBarcodeInstructions">Füge die Kundennummer ein, anschließend wähle die korrekte Barcodeart aus.</string>
|
||||
<string name="app_revision_fmt">Versions Information: <xliff:g id="app_revision_url">%s</xliff:g></string>
|
||||
<string name="importing">Importiere…</string>
|
||||
<string name="exporting">Exportiere…</string>
|
||||
|
||||
<string name="importExportHelp">Gesicherte Daten ermöglichen das Verschieben der Kundenkarten auf ein anderes Gerät.</string>
|
||||
<string name="importSuccessfulTitle">Import erfolgreich</string>
|
||||
<string name="importFailedTitle">Import fehlgeschlagen</string>
|
||||
<string name="exportSuccessfulTitle">Export erfolgreich</string>
|
||||
<string name="exportFailedTitle">Export fehlgeschlagen</string>
|
||||
<string name="exportOptionExplanation">Die Datei wird ins Wurzelverzeichnis des externen Speichers geschrieben.</string>
|
||||
<string name="importOptionFilesystemTitle">Importiere vom Dateisystem</string>
|
||||
<string name="importOptionFilesystemExplanation">Wähle eine Datei im Speicher aus.</string>
|
||||
<string name="importOptionFilesystemButton">Vom Dateisystem</string>
|
||||
<string name="importOptionApplicationTitle">Importiere vom Dateisystem</string>
|
||||
<string name="importOptionApplicationExplanation">Wähle eine Datei aus einer App wie Dropbox, Google Drive, oder deinem bevorzugten Dateisystem aus.</string>
|
||||
<string name="importOptionApplicationButton">Nutze eine externe App</string>
|
||||
<string name="importOptionFixedTitle">Importiere vom Export Ort</string>
|
||||
<string name="importOptionFixedExplanation">Importiere von derselben Stelle, wo die exportiere Datei liegen würde.</string>
|
||||
<string name="importOptionFixedButton">Verwende die exportierte Stelle</string>
|
||||
<string name="sendLabel">Senden…</string>
|
||||
|
||||
</resources>
|
||||
79
app/src/main/res/values-fr/strings.xml
Normal file
@@ -0,0 +1,79 @@
|
||||
<resources
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
|
||||
<string name="app_name">Loyalty Card Keychain</string>
|
||||
<string name="action_add">Ajouter</string>
|
||||
|
||||
<string name="noGiftCards">Pas de carte de fidélité enregistrée. Cliquez sur le bouton "+" (plus) pour commencer.\n\nLoyalty Card Locker vous permet d\'enregistrer vos cartes de fidélité sur votre téléphone pour toujours les avoir à portée de main.</string>
|
||||
|
||||
<string name="storeName">Nom</string>
|
||||
<string name="note">Note</string>
|
||||
<string name="cardId">Numéro</string>
|
||||
<string name="barcodeType">Type de code-barres</string>
|
||||
|
||||
<string name="cancel">Annuler</string>
|
||||
<string name="save">Enregistrer</string>
|
||||
<string name="capture">Flasher</string>
|
||||
<string name="enterCard">Mode manuel</string>
|
||||
<string name="edit">Modifier</string>
|
||||
<string name="delete">Supprimer</string>
|
||||
<string name="confirm">Confirmer</string>
|
||||
<string name="deleteTitle">Supprimer la carte de fidélité</string>
|
||||
<string name="deleteConfirmation">Confirmez que vous souhaitez supprimer cette carte</string>
|
||||
<string name="ok">OK</string>
|
||||
<string name="copy_to_clipboard">Copier le numéro dans le presse-papier</string>
|
||||
|
||||
<string name="editCardTitle">Modifier la carte de fidélité</string>
|
||||
<string name="addCardTitle">Ajouter une carte de fidélité</string>
|
||||
<string name="viewCardTitle">Voir la carte de fidélité</string>
|
||||
<string name="scanCardBarcode">Flasher le code-barres de la carte</string>
|
||||
|
||||
<string name="barcodeImageDescription">Image du code-barres de la carte</string>
|
||||
|
||||
<string name="noStoreError">Aucun nom n\'a été saisi</string>
|
||||
<string name="noCardIdError">Aucun numéro n\'a été saisi</string>
|
||||
|
||||
<string name="cardIdFormat">%1$s: %2$s</string>
|
||||
|
||||
<string name="importExport">Importer/Exporter</string>
|
||||
<string name="importName">Importer</string>
|
||||
<string name="exportName">Exporter</string>
|
||||
<string name="importedFrom">Importé depuis : %1$s</string>
|
||||
<string name="exportedTo">Exporté vers : %1$s</string>
|
||||
<string name="fileMissing">Fichier manquant : %1$s</string>
|
||||
<string name="importFailed">Échec de l\'import : %1$s</string>
|
||||
<string name="exportFailed">Échec de l\'export : %1$s</string>
|
||||
<string name="importing">Import …</string>
|
||||
<string name="exporting">Export …</string>
|
||||
<string name="noExternalStoragePermissionError">Impossible d\'importer ou d\'exporter les données sans l\'autorisation d\'accès au stockage externe</string>
|
||||
|
||||
<string name="about">À propos</string>
|
||||
<string name="app_copyright_fmt">Copyright 2016-<xliff:g>%s</xliff:g> Branden Archer</string>
|
||||
<string name="app_license">Licence GPLv3.</string>
|
||||
<string name="about_title_fmt">À propos de <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="debug_version_fmt">Version : <xliff:g id="version">%s</xliff:g></string>
|
||||
<string name="app_revision_fmt">Notes sur les versions : <xliff:g id="app_revision_url">%s</xliff:g></string>
|
||||
<string name="app_libraries"><xliff:g id="app_name">%s</xliff:g> utilise les bibliothèques-tierces suivantes : <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
|
||||
<string name="selectBarcodeTitle">Choisissez le code-barre</string>
|
||||
<string name="enterBarcodeInstructions">Saisissez les chiffres du code-barres et sélectionnez l\'image qui le représente</string>
|
||||
|
||||
<string name="copy_to_clipboard_toast">Numéro de carte copié dans le presse-papier</string>
|
||||
|
||||
<string name="importExportHelp">Exporter vos données vous permet de récupérer vos cartes sur un autre appareil.</string>
|
||||
<string name="importSuccessfulTitle">Importé avec succès</string>
|
||||
<string name="importFailedTitle">Échec de l\'import</string>
|
||||
<string name="exportSuccessfulTitle">Exporté avec succès</string>
|
||||
<string name="exportFailedTitle">Échec de l\'export</string>
|
||||
<string name="exportOptionExplanation">Les données sont sauvegardées à la racine du stockage externe.</string>
|
||||
<string name="importOptionFilesystemTitle">Importer depuis le système de fichiers.</string>
|
||||
<string name="importOptionFilesystemExplanation">Choisissez le fichier à importer.</string>
|
||||
<string name="importOptionFilesystemButton">Système de fichiers</string>
|
||||
<string name="importOptionApplicationTitle">Importer depuis le système de fichiers</string>
|
||||
<string name="importOptionApplicationExplanation">Utilisez une application externe comme Dropbox, Google Drive, ou votre gestionnaire de fichiers favori pour ouvrir un fichier.</string>
|
||||
<string name="importOptionApplicationButton">Application externe</string>
|
||||
<string name="importOptionFixedTitle">Importer depuis le même emplacement que pour l\'export</string>
|
||||
<string name="importOptionFixedExplanation">Importe les données depuis le même emplacement que celui défini pour l\'export.</string>
|
||||
<string name="importOptionFixedButton">Utiliser l\'emplacement de l\'export</string>
|
||||
<string name="sendLabel">Envoyer…</string>
|
||||
</resources>
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
<string name="cancel">Annulla</string>
|
||||
<string name="save">Salva</string>
|
||||
<string name="capture">Salva tessera</string>
|
||||
<string name="capture">Scansione carta</string>
|
||||
<string name="edit">Modifica</string>
|
||||
<string name="delete">Elimina</string>
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
<string name="importExport">Importa/Esporta</string>
|
||||
<string name="importName">Importa</string>
|
||||
<string name="exportName">Esporta</string>
|
||||
<string name="importExportHelp">I dati sono stati importati in o esportati dal file LoyaltyCardLocker.csv sulla memoria esterna</string>
|
||||
<string name="importedFrom">Importato da: %1$s</string>
|
||||
<string name="exportedTo">Esportato in: %1$s</string>
|
||||
<string name="fileMissing">File mancante: %1$s</string>
|
||||
@@ -54,4 +53,23 @@
|
||||
<string name="enterBarcodeInstructions">Digita il valore del codice a barre, quindi seleziona l\'immagine che rappresenta il codice a barre che vuoi usare.</string>
|
||||
<string name="copy_to_clipboard">Copia ID negli appunti</string>
|
||||
<string name="copy_to_clipboard_toast">ID della carta copiato negli appunti</string>
|
||||
<string name="confirm">Conferma</string>
|
||||
<string name="deleteTitle">Rimuovi carta fedeltà</string>
|
||||
<string name="deleteConfirmation">Conferma che vuoi eliminare questa carta.</string>
|
||||
<string name="importExportHelp">Fare il backup dei dati ti permette di spostare le tue tessere da un dispositivo ad un altro.</string>
|
||||
<string name="importSuccessfulTitle">Importazione avvenuta con successo</string>
|
||||
<string name="importFailedTitle">Importazione fallita</string>
|
||||
<string name="exportSuccessfulTitle">Esportazione avvenuta con successo</string>
|
||||
<string name="exportFailedTitle">Esportazione fallita</string>
|
||||
<string name="exportOptionExplanation">I dati sono stati scritti nella cartella principale della memoria esterna.</string>
|
||||
<string name="importOptionFilesystemTitle">Importa dal file system</string>
|
||||
<string name="importOptionFilesystemExplanation">Scegli un file dal file system.</string>
|
||||
<string name="importOptionFilesystemButton">Dal file system</string>
|
||||
<string name="importOptionApplicationTitle">Importa dal file system</string>
|
||||
<string name="importOptionApplicationExplanation">Usa un\'applicazione esterna come Dropbox, Google Drive o il tuo file manager preferito per aprire il file.</string>
|
||||
<string name="importOptionApplicationButton">Usa un\'applicazione esterna</string>
|
||||
<string name="importOptionFixedTitle">Importa da un altro posto</string>
|
||||
<string name="importOptionFixedExplanation">Importa dallo stesso posto del file system dove si è esportato.</string>
|
||||
<string name="importOptionFixedButton">Usa luogo dell\'esportazione</string>
|
||||
<string name="sendLabel">Invia…</string>
|
||||
</resources>
|
||||
|
||||
79
app/src/main/res/values-lt/strings.xml
Normal file
@@ -0,0 +1,79 @@
|
||||
<resources
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
|
||||
<string name="app_name">Loyalty Card Keychain</string>
|
||||
<string name="action_add">Pridėti</string>
|
||||
|
||||
<string name="noGiftCards">Šiuo metu neturite nė vienos įvestos lojalumo kortelės. Paspauskite "+" (pliuso) pliuso mygtuką, kad pradėtumėte.\n\nLoyalty Card Locker leidžia Jums visada nešiotis lojalumo kortelių informaciją savo telefone ar planšetėje, taip jos visada pasiekiamos.</string>
|
||||
|
||||
<string name="storeName">Parduotuvė</string>
|
||||
<string name="note">Užrašas</string>
|
||||
<string name="cardId">Kortelės ID</string>
|
||||
<string name="barcodeType">Brūkšninio kodo tipas</string>
|
||||
|
||||
<string name="cancel">Atšaukti</string>
|
||||
<string name="save">Išsaugoti</string>
|
||||
<string name="capture">Nufotografuoti kortelę</string>
|
||||
<string name="enterCard">Įvesti kortelę</string>
|
||||
<string name="edit">Redaguoti</string>
|
||||
<string name="delete">Ištrinti</string>
|
||||
<string name="confirm">Patvirtinti</string>
|
||||
<string name="deleteTitle">Panaikinti lojalumo kortelę</string>
|
||||
<string name="deleteConfirmation">Prašome patvirtinti jog Jūs norite panaikinti šią lojalumo kortelę.</string>
|
||||
<string name="ok">Gerai</string>
|
||||
<string name="copy_to_clipboard">Nukopijuoti ID į iškarpinę</string>
|
||||
|
||||
<string name="editCardTitle">Redaguoti lojalumo kortelę</string>
|
||||
<string name="addCardTitle">Pridėti lojalumo kortelę</string>
|
||||
<string name="viewCardTitle">Paeržiūrėti lojalumo kortelę</string>
|
||||
<string name="scanCardBarcode">Nuskanuokite kortelės brūkšninį kodą</string>
|
||||
|
||||
<string name="barcodeImageDescription">Kortelės brūkšninio kodo paveikslėlis</string>
|
||||
|
||||
<string name="noStoreError">Parduotuvė neįvesta</string>
|
||||
<string name="noCardIdError">Neįvestas kortelės ID</string>
|
||||
|
||||
<string name="cardIdFormat">%1$s: %2$s</string>
|
||||
|
||||
<string name="importExport">Importuoti/Exportuoti</string>
|
||||
<string name="importName">Importuoti</string>
|
||||
<string name="exportName">Exportuoti</string>
|
||||
<string name="importedFrom">Importuota iš: %1$s</string>
|
||||
<string name="exportedTo">Eksportuota į: %1$s</string>
|
||||
<string name="fileMissing">Failas nerastas: %1$s</string>
|
||||
<string name="importFailed">Nepavyko importuoti: %1$s</string>
|
||||
<string name="exportFailed">Nepavyko eksportuoti: %1$s</string>
|
||||
<string name="importing">Importuoja…</string>
|
||||
<string name="exporting">Eksportuoja…</string>
|
||||
<string name="noExternalStoragePermissionError">Negalima importuoti/eksportuoti kortelių be išorinės atminties leidimo</string>
|
||||
|
||||
<string name="about">Apie</string>
|
||||
<string name="app_copyright_fmt">Visos teisės saugomos 2016-<xliff:g>%s</xliff:g> Branden Archer</string>
|
||||
<string name="app_license">Licenzijuota pagal GPLv3.</string>
|
||||
<string name="about_title_fmt">Apie <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="debug_version_fmt">Versija: <xliff:g id="version">%s</xliff:g></string>
|
||||
<string name="app_revision_fmt">Revizijos informacija: <xliff:g id="app_revision_url">%s</xliff:g></string>
|
||||
<string name="app_libraries"><xliff:g id="app_name">%s</xliff:g> naudoja šias trečiosios šalies bibliotekas: <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
|
||||
<string name="selectBarcodeTitle">Pasirinkite brūkšninį kodą</string>
|
||||
<string name="enterBarcodeInstructions">Enter the barcode value then select the image which represents the barcode you want to use</string>
|
||||
|
||||
<string name="copy_to_clipboard_toast">Kortelės ID nukopijuota į iškarpinę</string>
|
||||
|
||||
<!-- needs translated --><string name="importExportHelp">Backed up data can allow you to move your cards to another device.</string>
|
||||
<!-- needs translated --><string name="importSuccessfulTitle">Import successful</string>
|
||||
<!-- needs translated --><string name="importFailedTitle">Import failed</string>
|
||||
<!-- needs translated --><string name="exportSuccessfulTitle">Export successful</string>
|
||||
<!-- needs translated --><string name="exportFailedTitle">Export failed</string>
|
||||
<!-- needs translated --><string name="exportOptionExplanation">Data is written to the top directory in external storage.</string>
|
||||
<!-- needs translated --><string name="importOptionFilesystemTitle">Import from filesystem</string>
|
||||
<!-- needs translated --><string name="importOptionFilesystemExplanation">Choose a specific file from the filesystem.</string>
|
||||
<!-- needs translated --><string name="importOptionFilesystemButton">From filesystem</string>
|
||||
<!-- needs translated --><string name="importOptionApplicationTitle">Import from filesystem</string>
|
||||
<!-- needs translated --><string name="importOptionApplicationExplanation">Use an external application like Dropbox, Google Drive, or your favorite file manager to open a file.</string>
|
||||
<!-- needs translated --><string name="importOptionApplicationButton">Use external application</string>
|
||||
<!-- needs translated --><string name="importOptionFixedTitle">Import from export location</string>
|
||||
<!-- needs translated --><string name="importOptionFixedExplanation">Import from the same location on the filesystem that is written to on export.</string>
|
||||
<!-- needs translated --><string name="importOptionFixedButton">Use export location</string>
|
||||
<!-- needs translated --> <string name="sendLabel">Send…</string>
|
||||
</resources>
|
||||
@@ -32,7 +32,6 @@
|
||||
<string name="importExport">Importeer/Exporteer</string>
|
||||
<string name="importName">Importeer</string>
|
||||
<string name="exportName">Exporteer</string>
|
||||
<string name="importExportHelp">Data is geïmporteerd van of geëxporteerd naar LoyaltyCardLocker.csv op externe opslag</string>
|
||||
<string name="importedFrom">Geïmporteerd van: %1$s</string>
|
||||
<string name="exportedTo">Geëxporteerd naar: %1$s</string>
|
||||
<string name="fileMissing">Bestand niet gevonden: %1$s</string>
|
||||
@@ -54,4 +53,24 @@
|
||||
<string name="enterBarcodeInstructions">Voer de waarde van de barcode in en kies daarna de afbeelding die de barcode die je wil gebruiken representeert</string>
|
||||
<string name="copy_to_clipboard">Kopieer het ID naar het klembord</string>
|
||||
<string name="copy_to_clipboard_toast">Het ID is naar het klembord gekopieerd</string>
|
||||
<string name="confirm">Bevestig</string>
|
||||
<string name="deleteConfirmation">Bevestig deze kaart te verwijderen.</string>
|
||||
<string name="deleteTitle">Verwijder kaart</string>
|
||||
|
||||
<string name="importExportHelp">Data die is geback-upt maakt het mogelijk om je klantenkaarten naar een ander apparaat te verplaatsen.</string>
|
||||
<string name="importSuccessfulTitle">Importeren succesvol</string>
|
||||
<string name="importFailedTitle">Importeren mislukte</string>
|
||||
<string name="exportSuccessfulTitle">Exporteren succesvol</string>
|
||||
<string name="exportFailedTitle">Exporteren mislukt</string>
|
||||
<string name="exportOptionExplanation">Data is weggeschreven naar de hoogste map in externe opslag.</string>
|
||||
<string name="importOptionFilesystemTitle">Importeer van filesysteem</string>
|
||||
<string name="importOptionFilesystemExplanation">Kies een specifiek bestand van het filesysteem.</string>
|
||||
<string name="importOptionFilesystemButton">Van filesysteem</string>
|
||||
<string name="importOptionApplicationTitle">Importeer van filesysteem</string>
|
||||
<string name="importOptionApplicationExplanation">Gebruik een externe applicatie zoals Dropbox, Google Drive of je favoriete bestandsbeheer om een bestand te openen.</string>
|
||||
<string name="importOptionApplicationButton">Gebruik externe applicatie</string>
|
||||
<string name="importOptionFixedTitle">Importeer van exporteerlocatie</string>
|
||||
<string name="importOptionFixedExplanation">Importeer van zelfde locatie op het filesysteem waar tijdens exporteren naar geschreven is.</string>
|
||||
<string name="importOptionFixedButton">gebruik exporteerlocaite</string>
|
||||
<string name="sendLabel">Verzend…</string>
|
||||
</resources>
|
||||
|
||||
@@ -7,4 +7,8 @@
|
||||
<dimen name="no_data_padding">22dp</dimen>
|
||||
|
||||
<dimen name="barcode_disp_height">200dp</dimen>
|
||||
|
||||
<dimen name="text_size_medium">18sp</dimen>
|
||||
<dimen name="text_size_large">22sp</dimen>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<resources
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
|
||||
<string name="app_name">Loyalty Card Locker</string>
|
||||
<string name="app_name">Loyalty Card Keychain</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>
|
||||
@@ -17,8 +17,12 @@
|
||||
<string name="enterCard">Enter Card</string>
|
||||
<string name="edit">Edit</string>
|
||||
<string name="delete">Delete</string>
|
||||
<string name="confirm">Confirm</string>
|
||||
<string name="deleteTitle">Remove Loyalty Card</string>
|
||||
<string name="deleteConfirmation">Please confirm that you want to delete this card.</string>
|
||||
<string name="ok">OK</string>
|
||||
<string name="copy_to_clipboard">Copy ID to clipboard</string>
|
||||
<string name="sendLabel">Send…</string>
|
||||
|
||||
<string name="editCardTitle">Edit Loyalty Card</string>
|
||||
<string name="addCardTitle">Add Loyalty Card</string>
|
||||
@@ -36,15 +40,29 @@
|
||||
<string name="importExport">Import/Export</string>
|
||||
<string name="importName">Import</string>
|
||||
<string name="exportName">Export</string>
|
||||
<string name="importExportHelp">Data is imported to/exported from LoyaltyCardLocker.csv on external storage</string>
|
||||
<string name="importExportHelp">Backed up data can allow you to move your cards to another device.</string>
|
||||
<string name="importedFrom">Imported from: %1$s</string>
|
||||
<string name="exportedTo">Exported to: %1$s</string>
|
||||
<string name="fileMissing">File missing: %1$s</string>
|
||||
<string name="importSuccessfulTitle">Import successful</string>
|
||||
<string name="importFailedTitle">Import failed</string>
|
||||
<string name="importFailed">Failed to import: %1$s</string>
|
||||
<string name="exportSuccessfulTitle">Export successful</string>
|
||||
<string name="exportFailedTitle">Export failed</string>
|
||||
<string name="exportFailed">Failed to export: %1$s</string>
|
||||
<string name="importing">Importing…</string>
|
||||
<string name="exporting">Exporting…</string>
|
||||
<string name="noExternalStoragePermissionError">Unable to import or export cards without the external storage permission</string>
|
||||
<string name="exportOptionExplanation">Data is written to the top directory in external storage.</string>
|
||||
<string name="importOptionFilesystemTitle">Import from filesystem</string>
|
||||
<string name="importOptionFilesystemExplanation">Choose a specific file from the filesystem.</string>
|
||||
<string name="importOptionFilesystemButton">From filesystem</string>
|
||||
<string name="importOptionApplicationTitle">Import from filesystem</string>
|
||||
<string name="importOptionApplicationExplanation">Use an external application like Dropbox, Google Drive, or your favorite file manager to open a file.</string>
|
||||
<string name="importOptionApplicationButton">Use external application</string>
|
||||
<string name="importOptionFixedTitle">Import from export location</string>
|
||||
<string name="importOptionFixedExplanation">Import from the same location on the filesystem that is written to on export.</string>
|
||||
<string name="importOptionFixedButton">Use export location</string>
|
||||
|
||||
<string name="about">About</string>
|
||||
<string name="app_copyright_fmt">Copyright 2016-<xliff:g>%s</xliff:g> Branden Archer</string>
|
||||
@@ -59,4 +77,4 @@
|
||||
|
||||
<string name="copy_to_clipboard_toast">Card ID copied to clipboard</string>
|
||||
|
||||
</resources>
|
||||
</resources>
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
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.net.Uri;
|
||||
import android.view.View;
|
||||
|
||||
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 static org.robolectric.Shadows.shadowOf;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
@RunWith(RobolectricGradleTestRunner.class)
|
||||
@Config(constants = BuildConfig.class, sdk = 17)
|
||||
public class ImportExportActivityTest
|
||||
{
|
||||
private void registerIntentHandler(String handler)
|
||||
{
|
||||
// Add something that will 'handle' the given intent type
|
||||
|
||||
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";
|
||||
info.activityInfo.exported = true;
|
||||
|
||||
Intent intent = new Intent(handler);
|
||||
if(handler.equals(Intent.ACTION_PICK))
|
||||
{
|
||||
intent.setData(Uri.parse("file://"));
|
||||
}
|
||||
|
||||
if(handler.equals(Intent.ACTION_GET_CONTENT))
|
||||
{
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
intent.setType("*/*");
|
||||
}
|
||||
|
||||
packageManager.addResolveInfoForIntent(intent, info);
|
||||
}
|
||||
|
||||
private void checkVisibility(Activity activity, int state, int divider, int title, int message, int button)
|
||||
{
|
||||
View dividerView = activity.findViewById(divider);
|
||||
View titleView = activity.findViewById(title);
|
||||
View messageView = activity.findViewById(message);
|
||||
View buttonView = activity.findViewById(button);
|
||||
|
||||
assertEquals(state, dividerView.getVisibility());
|
||||
assertEquals(state, titleView.getVisibility());
|
||||
assertEquals(state, messageView.getVisibility());
|
||||
assertEquals(state, buttonView.getVisibility());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImportFilesystemOption()
|
||||
{
|
||||
for(boolean isInstalled : new Boolean[]{false, true})
|
||||
{
|
||||
int visibility = isInstalled ? View.VISIBLE : View.GONE;
|
||||
|
||||
if(isInstalled)
|
||||
{
|
||||
registerIntentHandler(Intent.ACTION_PICK);
|
||||
}
|
||||
|
||||
Activity activity = Robolectric.setupActivity(ImportExportActivity.class);
|
||||
|
||||
checkVisibility(activity, visibility, R.id.dividerImportFilesystem,
|
||||
R.id.importOptionFilesystemTitle, R.id.importOptionFilesystemExplanation,
|
||||
R.id.importOptionFilesystemButton);
|
||||
|
||||
// Should always be gone, as its provider is never installed
|
||||
checkVisibility(activity, View.GONE, R.id.dividerImportApplication,
|
||||
R.id.importOptionApplicationTitle, R.id.importOptionApplicationExplanation,
|
||||
R.id.importOptionApplicationButton);
|
||||
|
||||
// Import from file system should always be present
|
||||
|
||||
checkVisibility(activity, View.VISIBLE, R.id.dividerImportFixed,
|
||||
R.id.importOptionFixedTitle, R.id.importOptionFixedExplanation,
|
||||
R.id.importOptionFixedButton);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImportApplicationOption()
|
||||
{
|
||||
for(boolean isInstalled : new Boolean[]{false, true})
|
||||
{
|
||||
int visibility = isInstalled ? View.VISIBLE : View.GONE;
|
||||
|
||||
if(isInstalled)
|
||||
{
|
||||
registerIntentHandler(Intent.ACTION_GET_CONTENT);
|
||||
}
|
||||
|
||||
Activity activity = Robolectric.setupActivity(ImportExportActivity.class);
|
||||
|
||||
checkVisibility(activity, visibility, R.id.dividerImportApplication,
|
||||
R.id.importOptionApplicationTitle, R.id.importOptionApplicationExplanation,
|
||||
R.id.importOptionApplicationButton);
|
||||
|
||||
// Should always be gone, as its provider is never installed
|
||||
checkVisibility(activity, View.GONE, R.id.dividerImportFilesystem,
|
||||
R.id.importOptionFilesystemTitle, R.id.importOptionFilesystemExplanation,
|
||||
R.id.importOptionFilesystemButton);
|
||||
|
||||
// Import from file system should always be present
|
||||
|
||||
checkVisibility(activity, View.VISIBLE, R.id.dividerImportFixed,
|
||||
R.id.importOptionFixedTitle, R.id.importOptionFixedExplanation,
|
||||
R.id.importOptionFixedButton);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllOptionsAvailable()
|
||||
{
|
||||
registerIntentHandler(Intent.ACTION_PICK);
|
||||
registerIntentHandler(Intent.ACTION_GET_CONTENT);
|
||||
|
||||
Activity activity = Robolectric.setupActivity(ImportExportActivity.class);
|
||||
|
||||
checkVisibility(activity, View.VISIBLE, R.id.dividerImportApplication,
|
||||
R.id.importOptionApplicationTitle, R.id.importOptionApplicationExplanation,
|
||||
R.id.importOptionApplicationButton);
|
||||
|
||||
checkVisibility(activity, View.VISIBLE, R.id.dividerImportFilesystem,
|
||||
R.id.importOptionFilesystemTitle, R.id.importOptionFilesystemExplanation,
|
||||
R.id.importOptionFilesystemButton);
|
||||
|
||||
checkVisibility(activity, View.VISIBLE, R.id.dividerImportFixed,
|
||||
R.id.importOptionFixedTitle, R.id.importOptionFixedExplanation,
|
||||
R.id.importOptionFixedButton);
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package protect.card_locker;
|
||||
import android.app.Activity;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.os.Environment;
|
||||
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
|
||||
@@ -15,12 +16,14 @@ import org.robolectric.annotation.Config;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.util.Calendar;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
@RunWith(RobolectricGradleTestRunner.class)
|
||||
@@ -109,7 +112,7 @@ public class ImportExportTest
|
||||
@Test
|
||||
public void multipleCardsExportImport() throws IOException
|
||||
{
|
||||
final int NUM_CARDS = 1000;
|
||||
final int NUM_CARDS = 10;
|
||||
|
||||
for(DataFormat format : DataFormat.values())
|
||||
{
|
||||
@@ -144,7 +147,7 @@ public class ImportExportTest
|
||||
@Test
|
||||
public void importExistingCardsNotReplace() throws IOException
|
||||
{
|
||||
final int NUM_CARDS = 1000;
|
||||
final int NUM_CARDS = 10;
|
||||
|
||||
for(DataFormat format : DataFormat.values())
|
||||
{
|
||||
@@ -177,7 +180,7 @@ public class ImportExportTest
|
||||
@Test
|
||||
public void corruptedImportNothingSaved() throws IOException
|
||||
{
|
||||
final int NUM_CARDS = 1000;
|
||||
final int NUM_CARDS = 10;
|
||||
|
||||
for(DataFormat format : DataFormat.values())
|
||||
{
|
||||
@@ -205,32 +208,63 @@ public class ImportExportTest
|
||||
}
|
||||
}
|
||||
|
||||
class TestTaskCompleteListener implements ImportExportTask.TaskCompleteListener
|
||||
{
|
||||
Boolean success;
|
||||
File file;
|
||||
|
||||
public void onTaskComplete(boolean success, File file)
|
||||
{
|
||||
this.success = success;
|
||||
this.file = file;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void useImportExportTask()
|
||||
{
|
||||
final int NUM_CARDS = 10;
|
||||
|
||||
final File sdcardDir = Environment.getExternalStorageDirectory();
|
||||
final File exportFile = new File(sdcardDir, "LoyaltyCardLocker.csv");
|
||||
|
||||
for(DataFormat format : DataFormat.values())
|
||||
{
|
||||
addLoyaltyCards(NUM_CARDS);
|
||||
|
||||
// Export to whatever the default location is
|
||||
ImportExportTask task = new ImportExportTask(activity, false, format);
|
||||
TestTaskCompleteListener listener = new TestTaskCompleteListener();
|
||||
|
||||
// Export to the file
|
||||
ImportExportTask task = new ImportExportTask(activity, false, format, exportFile, listener);
|
||||
task.execute();
|
||||
|
||||
// Actually run the task to completion
|
||||
Robolectric.flushBackgroundThreadScheduler();
|
||||
|
||||
// Check that the listener was executed
|
||||
assertNotNull(listener.success);
|
||||
assertEquals(true, listener.success);
|
||||
assertNotNull(listener.file);
|
||||
assertEquals(exportFile, listener.file);
|
||||
|
||||
clearDatabase();
|
||||
|
||||
// Import everything back from the default location
|
||||
|
||||
task = new ImportExportTask(activity, true, format);
|
||||
listener = new TestTaskCompleteListener();
|
||||
|
||||
task = new ImportExportTask(activity, true, format, exportFile, listener);
|
||||
task.execute();
|
||||
|
||||
// Actually run the task to completion
|
||||
Robolectric.flushBackgroundThreadScheduler();
|
||||
|
||||
// Check that the listener was executed
|
||||
assertNotNull(listener.success);
|
||||
assertEquals(true, listener.success);
|
||||
assertNotNull(listener.file);
|
||||
assertEquals(exportFile, listener.file);
|
||||
|
||||
assertEquals(NUM_CARDS, db.getLoyaltyCardCount());
|
||||
|
||||
checkLoyaltyCards();
|
||||
|
||||
@@ -5,7 +5,7 @@ buildscript {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:2.1.2'
|
||||
classpath 'com.android.tools.build:gradle:2.1.3'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
|
||||
4
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
||||
#Tue May 03 10:42:45 EDT 2016
|
||||
#Sun Dec 04 15:17:03 EST 2016
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
|
||||
|
||||