- Create an abstract base class for MainActivity
- Rename old MainActivity InternalMainActivity
- Add ExternalMainActivity to show external tokens
- Extend InternalMainActivity to scan for NFC devices and start
ExternalMainActivity if presented
- Centralize TokenPersistence to *MainActivity
- Extend all other activities to execute actions and return their
results
- Add related strings
---
app/src/main/AndroidManifest.xml | 7 +-
.../fedorahosted/freeotp/ExternalMainActivity.java | 142 +++++++++++++++++++++
.../fedorahosted/freeotp/InternalMainActivity.java | 126 ++++++++++++++++++
.../org/fedorahosted/freeotp/MainActivity.java | 84 +++++-------
.../org/fedorahosted/freeotp/TokenAdapter.java | 21 +--
.../org/fedorahosted/freeotp/add/AddActivity.java | 10 +-
.../org/fedorahosted/freeotp/add/BaseActivity.java | 7 +
.../org/fedorahosted/freeotp/add/ScanActivity.java | 23 +++-
.../fedorahosted/freeotp/edit/BaseActivity.java | 22 ----
.../fedorahosted/freeotp/edit/DeleteActivity.java | 22 +++-
.../fedorahosted/freeotp/edit/EditActivity.java | 45 ++++---
app/src/main/res/layout/main.xml | 4 +-
app/src/main/res/values/strings.xml | 15 ++-
13 files changed, 402 insertions(+), 126 deletions(-)
create mode 100644 app/src/main/java/org/fedorahosted/freeotp/ExternalMainActivity.java
create mode 100644 app/src/main/java/org/fedorahosted/freeotp/InternalMainActivity.java
create mode 100644 app/src/main/java/org/fedorahosted/freeotp/add/BaseActivity.java
delete mode 100644 app/src/main/java/org/fedorahosted/freeotp/edit/BaseActivity.java
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 0eeaa19..39a9cec 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -80,7 +80,12 @@
/>
<activity
- android:name=".MainActivity"
+ android:name=".ExternalMainActivity"
+ android:label="@string/nfc_app_name"
+ />
+
+ <activity
+ android:name=".InternalMainActivity"
android:label="@string/app_name"
android:clearTaskOnLaunch="true"
android:launchMode="singleTask"
diff --git a/app/src/main/java/org/fedorahosted/freeotp/ExternalMainActivity.java
b/app/src/main/java/org/fedorahosted/freeotp/ExternalMainActivity.java
new file mode 100644
index 0000000..d357f59
--- /dev/null
+++ b/app/src/main/java/org/fedorahosted/freeotp/ExternalMainActivity.java
@@ -0,0 +1,142 @@
+/*
+ * FreeOTP
+ *
+ * Authors: Petter Arvidsson <petter.arvidsson(a)fidesmo.com>
+ *
+ * Copyright (C) 2014 Petter Arvidsson, Fidesmo AB
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *
http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.fedorahosted.freeotp;
+
+import java.io.IOException;
+
+import static org.fedorahosted.freeotp.NfcHelpers.*;
+
+import android.content.Intent;
+import android.widget.Toast;
+import android.widget.TextView;
+import android.widget.GridView;
+import android.view.View;
+import android.os.Bundle;
+import android.nfc.NfcAdapter;
+import android.nfc.tech.IsoDep;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+
+public class ExternalMainActivity extends MainActivity {
+ private NfcAdapter mAdapter;
+ int tokenToDelete = -1;
+ String tokenToAdd = null;
+ AlertDialog dialog;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mAdapter = NfcAdapter.getDefaultAdapter(this);
+ onNewIntent(getIntent());
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ Intent intent = new Intent(this, ExternalMainActivity.class);
+ intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
+ enableForegroundDispatch(this, mAdapter, intent);
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ disableForegroundDispatch(this, mAdapter);
+ }
+
+ protected void deleteToken(int position) {
+ tokenToDelete = position;
+ dialog = new AlertDialog.Builder(this)
+ .setTitle(R.string.tap_dialog_title)
+ .setMessage(R.string.tap_to_delete)
+ .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int wich) {
+ tokenToDelete = -1;
+ }
+ })
+ .show();
+ }
+
+ protected void addToken(String tokenUri) {
+ tokenToAdd = tokenUri;
+ dialog = new AlertDialog.Builder(this)
+ .setTitle(R.string.tap_dialog_title)
+ .setMessage(R.string.tap_to_add)
+ .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int wich) {
+ tokenToAdd = null;
+ }
+ })
+ .show();
+ }
+
+ private void setUpTokenList(IsoDep tag) {
+ ExternalTokenPersistence persistence = null;
+ TextView view = (TextView)findViewById(android.R.id.empty);
+ if(tag != null) {
+ try {
+ persistence = new ExternalTokenPersistence(tag);
+ } catch(IOException ioe) {
+ Toast.makeText(this, R.string.failed_to_read_external_token,
Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ if(persistence != null) {
+ if(dialog != null) dialog.cancel();
+ view.setText(R.string.no_keys);
+
getActionBar().setBackgroundDrawable(getResources().getDrawable(android.R.color.black));
+ /*
+ * The following two lines are a fix for the following bug:
+ *
http://stackoverflow.com/questions/17076958/change-actionbar-color-progra...
+ */
+ getActionBar().setDisplayShowTitleEnabled(false);
+ getActionBar().setDisplayShowTitleEnabled(true);
+ if(tokenToDelete != -1) {
+ try {
+ persistence.delete(tokenToDelete);
+ } catch(IOException ioe) {
+ Toast.makeText(this, R.string.failed_to_read_external_token,
Toast.LENGTH_SHORT).show();
+ }
+ tokenToDelete = -1;
+ } else if(tokenToAdd != null) {
+ persistence.addWithToast(this, tokenToAdd);
+ tokenToAdd = null;
+ }
+
+ TokenAdapter adapter = new TokenAdapter(this, persistence);
+ ((GridView) findViewById(R.id.grid)).setAdapter(adapter);
+ if (adapter.getCount() == 0)
+ view.setVisibility(View.VISIBLE);
+ else
+ view.setVisibility(View.GONE);
+ } else {
+ view.setText(R.string.tap_external_token);
+ view.setVisibility(View.VISIBLE);
+ }
+ }
+
+ @Override
+ protected void onNewIntent(Intent intent) {
+ super.onNewIntent(intent);
+ setUpTokenList(getIsoTag(intent));
+ }
+
+}
diff --git a/app/src/main/java/org/fedorahosted/freeotp/InternalMainActivity.java
b/app/src/main/java/org/fedorahosted/freeotp/InternalMainActivity.java
new file mode 100644
index 0000000..e6c3021
--- /dev/null
+++ b/app/src/main/java/org/fedorahosted/freeotp/InternalMainActivity.java
@@ -0,0 +1,126 @@
+/*
+ * FreeOTP
+ *
+ * Authors: Nathaniel McCallum <npmccallum(a)redhat.com>
+ *
+ * Copyright (C) 2013 Nathaniel McCallum, Red Hat
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *
http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Portions Copyright 2009 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *
http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.fedorahosted.freeotp;
+
+import static org.fedorahosted.freeotp.NfcHelpers.*;
+import org.fedorahosted.freeotp.edit.EditActivity;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.database.DataSetObserver;
+import android.net.Uri;
+import android.os.Bundle;
+import android.nfc.NfcAdapter;
+import android.nfc.tech.IsoDep;
+import android.widget.GridView;
+import android.view.View;
+import android.widget.Toast;
+
+public class InternalMainActivity extends MainActivity {
+ private InternalTokenPersistence mTokenPersistence;
+ private TokenAdapter mTokenAdapter;
+ private DataSetObserver mDataSetObserver;
+ private NfcAdapter mAdapter;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mAdapter = NfcAdapter.getDefaultAdapter(this);
+ mTokenPersistence = new InternalTokenPersistence(this);
+ mTokenAdapter = new TokenAdapter(this, mTokenPersistence);
+ ((GridView) findViewById(R.id.grid)).setAdapter(mTokenAdapter);
+
+ mDataSetObserver = new DataSetObserver() {
+ @Override
+ public void onChanged() {
+ super.onChanged();
+ if (mTokenAdapter.getCount() == 0)
+ findViewById(android.R.id.empty).setVisibility(View.VISIBLE);
+ else
+ findViewById(android.R.id.empty).setVisibility(View.GONE);
+ }
+ };
+ mTokenAdapter.registerDataSetObserver(mDataSetObserver);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mTokenAdapter.notifyDataSetChanged();
+ enableForegroundDispatch(this, mAdapter, new Intent(this,
ExternalMainActivity.class));
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mTokenAdapter.notifyDataSetChanged();
+ disableForegroundDispatch(this, mAdapter);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mTokenAdapter.unregisterDataSetObserver(mDataSetObserver);
+ }
+
+ @Override
+ protected void onNewIntent(Intent intent) {
+ super.onNewIntent(intent);
+ Uri uri = intent.getData();
+ if (uri != null) {
+ mTokenPersistence.addWithToast(this, uri.toString());
+ }
+ }
+
+ protected void deleteToken(int position) {
+ mTokenPersistence.delete(position);
+ }
+
+ protected void addToken(String tokenUri) {
+ mTokenPersistence.addWithToast(this, tokenUri);
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ if(requestCode == EDIT_REQUEST_CODE && resultCode == RESULT_OK) {
+ InternalToken token =
(InternalToken)data.getSerializableExtra(EditActivity.EXTRA_TOKEN);
+ mTokenPersistence.save(token);
+ }
+ }
+
+}
diff --git a/app/src/main/java/org/fedorahosted/freeotp/MainActivity.java
b/app/src/main/java/org/fedorahosted/freeotp/MainActivity.java
index 1b9812d..968e140 100644
--- a/app/src/main/java/org/fedorahosted/freeotp/MainActivity.java
+++ b/app/src/main/java/org/fedorahosted/freeotp/MainActivity.java
@@ -36,67 +36,36 @@
package org.fedorahosted.freeotp;
-import org.fedorahosted.freeotp.add.AddActivity;
-import org.fedorahosted.freeotp.add.ScanActivity;
+import java.io.IOException;
+import org.fedorahosted.freeotp.add.ScanActivity;
+import org.fedorahosted.freeotp.add.AddActivity;
+import org.fedorahosted.freeotp.add.BaseActivity;
+import org.fedorahosted.freeotp.edit.DeleteActivity;
import android.app.Activity;
import android.content.Intent;
-import android.database.DataSetObserver;
import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
-import android.view.View;
import android.view.WindowManager.LayoutParams;
-import android.widget.GridView;
+import android.widget.Toast;
-public class MainActivity extends Activity implements OnMenuItemClickListener {
- private TokenAdapter mTokenAdapter;
- private InternalTokenPersistence mTokenPersistence;
- private DataSetObserver mDataSetObserver;
+public abstract class MainActivity extends Activity implements OnMenuItemClickListener {
+ public static final int DELETE_REQUEST_CODE = 1;
+ public static final int SCAN_REQUEST_CODE = 2;
+ public static final int ADD_REQUEST_CODE = 3;
+ public static final int EDIT_REQUEST_CODE = 4;
+ protected abstract void deleteToken(int position);
+ protected abstract void addToken(String tokenUri);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- onNewIntent(getIntent());
setContentView(R.layout.main);
- mTokenPersistence = new InternalTokenPersistence(this);
- mTokenAdapter = new TokenAdapter(this, mTokenPersistence);
- ((GridView) findViewById(R.id.grid)).setAdapter(mTokenAdapter);
-
// Don't permit screenshots since these might contain OTP codes.
getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE);
-
- mDataSetObserver = new DataSetObserver() {
- @Override
- public void onChanged() {
- super.onChanged();
- if (mTokenAdapter.getCount() == 0)
- findViewById(android.R.id.empty).setVisibility(View.VISIBLE);
- else
- findViewById(android.R.id.empty).setVisibility(View.GONE);
- }
- };
- mTokenAdapter.registerDataSetObserver(mDataSetObserver);
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- mTokenAdapter.notifyDataSetChanged();
- }
-
- @Override
- protected void onPause() {
- super.onPause();
- mTokenAdapter.notifyDataSetChanged();
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mTokenAdapter.unregisterDataSetObserver(mDataSetObserver);
}
@Override
@@ -111,14 +80,16 @@ public class MainActivity extends Activity implements
OnMenuItemClickListener {
@Override
public boolean onMenuItemClick(MenuItem item) {
+ Intent i;
switch (item.getItemId()) {
case R.id.action_scan:
- startActivity(new Intent(this, ScanActivity.class));
+ i = new Intent(this, ScanActivity.class);
+ startActivityForResult(i, SCAN_REQUEST_CODE);
overridePendingTransition(R.anim.fadein, R.anim.fadeout);
return true;
case R.id.action_add:
- startActivity(new Intent(this, AddActivity.class));
+ startActivityForResult(new Intent(this, AddActivity.class),
ADD_REQUEST_CODE);
return true;
case R.id.action_about:
@@ -130,11 +101,20 @@ public class MainActivity extends Activity implements
OnMenuItemClickListener {
}
@Override
- protected void onNewIntent(Intent intent) {
- super.onNewIntent(intent);
-
- Uri uri = intent.getData();
- if (uri != null)
- mTokenPersistence.addWithToast(this, uri.toString());
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if(resultCode == RESULT_OK) {
+ switch(requestCode) {
+ case DELETE_REQUEST_CODE:
+ int position = data.getIntExtra(DeleteActivity.EXTRA_POSITION, -1);
+ deleteToken(position);
+ break;
+ case ADD_REQUEST_CODE:
+ case SCAN_REQUEST_CODE:
+ String tokenUri = data.getStringExtra(BaseActivity.EXTRA_TOKEN_URI);
+ addToken(tokenUri);
+ break;
+ }
+ }
}
+
}
diff --git a/app/src/main/java/org/fedorahosted/freeotp/TokenAdapter.java
b/app/src/main/java/org/fedorahosted/freeotp/TokenAdapter.java
index 94baaab..e2c64b4 100644
--- a/app/src/main/java/org/fedorahosted/freeotp/TokenAdapter.java
+++ b/app/src/main/java/org/fedorahosted/freeotp/TokenAdapter.java
@@ -20,6 +20,9 @@
package org.fedorahosted.freeotp;
+import java.io.IOException;
+
+import android.app.Activity;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
@@ -44,8 +47,10 @@ public class TokenAdapter extends BaseReorderableAdapter {
private final LayoutInflater mLayoutInflater;
private final ClipboardManager mClipMan;
private final Map<String, TokenCode> mTokenCodes;
+ private final Activity mCtx;
- public TokenAdapter(Context ctx, TokenPersistence tokenPersistence) {
+ public TokenAdapter(Activity ctx, TokenPersistence tokenPersistence) {
+ mCtx = ctx;
mTokenPersistence = tokenPersistence;
mLayoutInflater = (LayoutInflater)
ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mClipMan = (ClipboardManager) ctx.getSystemService(Context.CLIPBOARD_SERVICE);
@@ -86,9 +91,8 @@ public class TokenAdapter extends BaseReorderableAdapter {
@Override
protected void bindView(View view, final int position) {
- final Context ctx = view.getContext();
TokenLayout tl = (TokenLayout) view;
- Token token = getItem(position);
+ final Token token = getItem(position);
int menu = token.isInternal() ? R.menu.editable_token : R.menu.token;
@@ -99,15 +103,16 @@ public class TokenAdapter extends BaseReorderableAdapter {
switch (item.getItemId()) {
case R.id.action_edit:
- i = new Intent(ctx, EditActivity.class);
- i.putExtra(EditActivity.EXTRA_POSITION, position);
- ctx.startActivity(i);
+ i = new Intent(mCtx, EditActivity.class);
+ i.putExtra(EditActivity.EXTRA_TOKEN, token);
+ mCtx.startActivityForResult(i, MainActivity.EDIT_REQUEST_CODE);
break;
case R.id.action_delete:
- i = new Intent(ctx, DeleteActivity.class);
+ i = new Intent(mCtx, DeleteActivity.class);
i.putExtra(DeleteActivity.EXTRA_POSITION, position);
- ctx.startActivity(i);
+ i.putExtra(DeleteActivity.EXTRA_TOKEN, token);
+ mCtx.startActivityForResult(i,
MainActivity.DELETE_REQUEST_CODE);
break;
}
diff --git a/app/src/main/java/org/fedorahosted/freeotp/add/AddActivity.java
b/app/src/main/java/org/fedorahosted/freeotp/add/AddActivity.java
index d996a4d..66b12e8 100644
--- a/app/src/main/java/org/fedorahosted/freeotp/add/AddActivity.java
+++ b/app/src/main/java/org/fedorahosted/freeotp/add/AddActivity.java
@@ -25,7 +25,6 @@ import java.net.URLEncoder;
import java.util.Locale;
import org.fedorahosted.freeotp.R;
-import org.fedorahosted.freeotp.InternalTokenPersistence;
import android.app.Activity;
import android.content.Intent;
@@ -41,7 +40,7 @@ import android.widget.Spinner;
import com.squareup.picasso.Picasso;
-public class AddActivity extends Activity implements View.OnClickListener,
CompoundButton.OnCheckedChangeListener {
+public class AddActivity extends BaseActivity implements View.OnClickListener,
CompoundButton.OnCheckedChangeListener {
private final int SHA1_OFFSET = 1;
private ImageButton mImage;
private EditText mIssuer;
@@ -129,9 +128,10 @@ public class AddActivity extends Activity implements
View.OnClickListener, Compo
}
}
- // Add the token
- if (new InternalTokenPersistence(this).addWithToast(this, uri) != null)
- finish();
+ Intent resultData = new Intent();
+ resultData.putExtra(EXTRA_TOKEN_URI, uri);
+ setResult(RESULT_OK, resultData);
+ finish();
break;
}
diff --git a/app/src/main/java/org/fedorahosted/freeotp/add/BaseActivity.java
b/app/src/main/java/org/fedorahosted/freeotp/add/BaseActivity.java
new file mode 100644
index 0000000..f68ab4b
--- /dev/null
+++ b/app/src/main/java/org/fedorahosted/freeotp/add/BaseActivity.java
@@ -0,0 +1,7 @@
+package org.fedorahosted.freeotp.add;
+
+import android.app.Activity;
+
+public abstract class BaseActivity extends Activity {
+ public static final String EXTRA_TOKEN_URI = "tokenUri";
+}
diff --git a/app/src/main/java/org/fedorahosted/freeotp/add/ScanActivity.java
b/app/src/main/java/org/fedorahosted/freeotp/add/ScanActivity.java
index 68fa5cf..9e29aa4 100644
--- a/app/src/main/java/org/fedorahosted/freeotp/add/ScanActivity.java
+++ b/app/src/main/java/org/fedorahosted/freeotp/add/ScanActivity.java
@@ -23,14 +23,14 @@ package org.fedorahosted.freeotp.add;
import java.util.List;
import org.fedorahosted.freeotp.R;
-import org.fedorahosted.freeotp.InternalToken;
-import org.fedorahosted.freeotp.InternalTokenPersistence;
import android.annotation.TargetApi;
import android.app.Activity;
+import android.content.Intent;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.Parameters;
+import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
@@ -44,7 +44,7 @@ import android.widget.ProgressBar;
import com.squareup.picasso.Callback;
import com.squareup.picasso.Picasso;
-public class ScanActivity extends Activity implements SurfaceHolder.Callback {
+public class ScanActivity extends BaseActivity implements SurfaceHolder.Callback {
private final CameraInfo mCameraInfo = new CameraInfo();
private final ScanAsyncTask mScanAsyncTask;
private final int mCameraId;
@@ -98,15 +98,22 @@ public class ScanActivity extends Activity implements
SurfaceHolder.Callback {
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
- InternalToken token = new
InternalTokenPersistence(ScanActivity.this).addWithToast(ScanActivity.this, result);
- if (token == null || token.getImage() == null) {
+
+ Uri uri = Uri.parse(result);
+
+ final Intent resultData = new Intent();
+ resultData.putExtra(EXTRA_TOKEN_URI, result);
+
+ String imageParameter = uri.getQueryParameter("image");
+ if(imageParameter == null) {
+ setResult(RESULT_OK, resultData);
finish();
return;
}
-
+ Uri imageUri = Uri.parse(imageParameter);
final ImageView image = (ImageView) findViewById(R.id.image);
Picasso.with(ScanActivity.this)
- .load(token.getImage())
+ .load(imageUri)
.placeholder(R.drawable.scan)
.into(image, new Callback() {
@Override
@@ -116,6 +123,7 @@ public class ScanActivity extends Activity implements
SurfaceHolder.Callback {
image.postDelayed(new Runnable() {
@Override
public void run() {
+ setResult(RESULT_OK, resultData);
finish();
}
}, 2000);
@@ -123,6 +131,7 @@ public class ScanActivity extends Activity implements
SurfaceHolder.Callback {
@Override
public void onError() {
+ setResult(RESULT_CANCELED);
finish();
}
});
diff --git a/app/src/main/java/org/fedorahosted/freeotp/edit/BaseActivity.java
b/app/src/main/java/org/fedorahosted/freeotp/edit/BaseActivity.java
deleted file mode 100644
index d81010e..0000000
--- a/app/src/main/java/org/fedorahosted/freeotp/edit/BaseActivity.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package org.fedorahosted.freeotp.edit;
-
-import android.app.Activity;
-import android.os.Bundle;
-
-public abstract class BaseActivity extends Activity {
- public static final String EXTRA_POSITION = "position";
- private int mPosition;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- // Get the position of the token. This MUST exist.
- mPosition = getIntent().getIntExtra(EXTRA_POSITION, -1);
- assert mPosition >= 0;
- }
-
- protected int getPosition() {
- return mPosition;
- }
-}
diff --git a/app/src/main/java/org/fedorahosted/freeotp/edit/DeleteActivity.java
b/app/src/main/java/org/fedorahosted/freeotp/edit/DeleteActivity.java
index 7da16fb..0ad2549 100644
--- a/app/src/main/java/org/fedorahosted/freeotp/edit/DeleteActivity.java
+++ b/app/src/main/java/org/fedorahosted/freeotp/edit/DeleteActivity.java
@@ -2,23 +2,30 @@ package org.fedorahosted.freeotp.edit;
import org.fedorahosted.freeotp.R;
import org.fedorahosted.freeotp.Token;
-import org.fedorahosted.freeotp.InternalTokenPersistence;
+import android.app.Activity;
import android.os.Bundle;
+import android.content.Intent;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import com.squareup.picasso.Picasso;
-public class DeleteActivity extends BaseActivity {
- private InternalTokenPersistence mTokenPersistence;
+public class DeleteActivity extends Activity {
+ public static final String EXTRA_TOKEN = "token";
+ public static final String EXTRA_POSITION = "position";
+ private int mPosition;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ // Get the position of the token. This MUST exist.
+ mPosition = getIntent().getIntExtra(EXTRA_POSITION, -1);
+ assert mPosition >= 0;
+ Token token = (Token)getIntent().getSerializableExtra(EXTRA_TOKEN);
setContentView(R.layout.delete);
- mTokenPersistence = new InternalTokenPersistence(this);
- Token token = mTokenPersistence.get(getPosition());
+
((TextView) findViewById(R.id.issuer)).setText(token.getIssuer());
((TextView) findViewById(R.id.label)).setText(token.getLabel());
Picasso.with(this)
@@ -29,6 +36,7 @@ public class DeleteActivity extends BaseActivity {
findViewById(R.id.cancel).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
+ setResult(RESULT_CANCELED);
finish();
}
});
@@ -36,7 +44,9 @@ public class DeleteActivity extends BaseActivity {
findViewById(R.id.delete).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- mTokenPersistence.delete(getPosition());
+ Intent resultData = new Intent();
+ resultData.putExtra(EXTRA_POSITION, mPosition);
+ setResult(RESULT_OK, resultData);
finish();
}
});
diff --git a/app/src/main/java/org/fedorahosted/freeotp/edit/EditActivity.java
b/app/src/main/java/org/fedorahosted/freeotp/edit/EditActivity.java
index d55a657..5c495d3 100644
--- a/app/src/main/java/org/fedorahosted/freeotp/edit/EditActivity.java
+++ b/app/src/main/java/org/fedorahosted/freeotp/edit/EditActivity.java
@@ -22,8 +22,8 @@ package org.fedorahosted.freeotp.edit;
import org.fedorahosted.freeotp.R;
import org.fedorahosted.freeotp.InternalToken;
-import org.fedorahosted.freeotp.InternalTokenPersistence;
+import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
@@ -36,7 +36,10 @@ import android.widget.ImageButton;
import com.squareup.picasso.Picasso;
-public class EditActivity extends BaseActivity implements TextWatcher,
View.OnClickListener {
+public class EditActivity extends Activity implements TextWatcher, View.OnClickListener
{
+ public static final String EXTRA_TOKEN = "token";
+
+ private InternalToken mToken;
private EditText mIssuer;
private EditText mLabel;
private ImageButton mImage;
@@ -50,7 +53,6 @@ public class EditActivity extends BaseActivity implements TextWatcher,
View.OnCl
private Uri mImageCurrent;
private Uri mImageDefault;
private Uri mImageDisplay;
- private InternalTokenPersistence mTokenPersistence;
private void showImage(Uri uri) {
mImageDisplay = uri;
@@ -72,19 +74,18 @@ public class EditActivity extends BaseActivity implements TextWatcher,
View.OnCl
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.edit);
-
+ mToken = (InternalToken)getIntent().getSerializableExtra(EXTRA_TOKEN);
// Get token values.
- mTokenPersistence = new InternalTokenPersistence(this);
- InternalToken token = (InternalToken)mTokenPersistence.get(getPosition());
- mIssuerCurrent = token.getIssuer();
- mLabelCurrent = token.getLabel();
- mImageCurrent = token.getImage();
- token.setIssuer(null);
- token.setLabel(null);
- token.setImage(null);
- mIssuerDefault = token.getIssuer();
- mLabelDefault = token.getLabel();
- mImageDefault = token.getImage();
+
+ mIssuerCurrent = mToken.getIssuer();
+ mLabelCurrent = mToken.getLabel();
+ mImageCurrent = mToken.getImage();
+ mToken.setIssuer(null);
+ mToken.setLabel(null);
+ mToken.setImage(null);
+ mIssuerDefault = mToken.getIssuer();
+ mLabelDefault = mToken.getLabel();
+ mImageDefault = mToken.getImage();
// Get references to widgets.
mIssuer = (EditText) findViewById(R.id.issuer);
@@ -152,13 +153,17 @@ public class EditActivity extends BaseActivity implements
TextWatcher, View.OnCl
break;
case R.id.save:
- InternalToken token =
(InternalToken)mTokenPersistence.get(getPosition());
- token.setIssuer(mIssuer.getText().toString());
- token.setLabel(mLabel.getText().toString());
- token.setImage(mImageDisplay);
- mTokenPersistence.save(token);
+ mToken.setIssuer(mIssuer.getText().toString());
+ mToken.setLabel(mLabel.getText().toString());
+ mToken.setImage(mImageDisplay);
+ Intent resultData = new Intent();
+ resultData.putExtra(EXTRA_TOKEN, mToken);
+ setResult(RESULT_OK, resultData);
+ finish();
+ break;
case R.id.cancel:
+ setResult(RESULT_CANCELED);
finish();
break;
}
diff --git a/app/src/main/res/layout/main.xml b/app/src/main/res/layout/main.xml
index a1770ae..1045568 100644
--- a/app/src/main/res/layout/main.xml
+++ b/app/src/main/res/layout/main.xml
@@ -31,7 +31,7 @@
android:layout_height="match_parent"
android:padding="8dp"
android:gravity="center"
- android:text="@string/no_keys"
+ android:text="@string/no_keys_or_tap"
/>
<GridView
@@ -48,4 +48,4 @@
android:verticalSpacing="8dp"
android:background="#E5E5E5"
/>
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 359026f..c4b55d3 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,13 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">FreeOTP</string>
+ <string name="nfc_app_name">FreeOTP (NFC)</string>
<string name="add">Add</string>
<string name="invalid_token">The token specified was
invalid!</string>
<string name="delete">Delete</string>
<string name="edit">Edit</string>
<string name="restore_defaults">Restore Defaults</string>
- <string name="no_keys">No OTP keys installed.</string>
- <string name="add_token">Add Token</string>
+ <string name="no_keys_or_tap">No OTP tokens on this device. To list
the tokens on an NFC device, tap it!</string>
+ <string name="no_keys">No OTP tokens on this device.</string>
+ <string name="add_token">Add token</string>
+ <string name="external_add_token">Tap NFC device to add
token</string>
+ <string name="external_add_token_validation_wrong">Fields are not
entered correctly</string>
<string name="scan_qr_code">Scan QR Code</string>
<string name="interval">Interval</string>
<string name="counter">Counter</string>
@@ -37,8 +41,13 @@
<string name="delete_summary">This is your last chance: if you delete
this token, it will be gone forever. It will not be disabled on the
server.</string>
<string name="delete_question">Delete this token?</string>
- <string name="external_token_needed">You need the NFC device to
generate a code</string>
<string name="failed_to_read_external_token">Failed to read the NFC
device</string>
+ <string name="tap_external_token">Tap the NFC device to refresh the
list of tokens</string>
+ <string name="external_token_needed">You need the NFC device to
generate a code</string>
+ <string name="cancel">Cancel</string>
+ <string name="tap_to_delete">Tap your NFC device to delete the
token.</string>
+ <string name="tap_to_add">Tap your NFC device to add the
token.</string>
+ <string name="tap_dialog_title">Tap NFC device</string>
<string-array name="algorithms">
<item>MD5</item>
<item>SHA1</item>
--
1.9.1