parent
ad0c2f46b8
commit
842d49b68f
4 changed files with 132 additions and 48 deletions
|
@ -42,7 +42,7 @@ import org.shadowice.flocke.andotp.R;
|
||||||
|
|
||||||
import static org.shadowice.flocke.andotp.Utilities.Settings.AuthMethod;
|
import static org.shadowice.flocke.andotp.Utilities.Settings.AuthMethod;
|
||||||
|
|
||||||
public class AuthenticateActivity extends BaseActivity
|
public class AuthenticateActivity extends ThemedActivity
|
||||||
implements EditText.OnEditorActionListener {
|
implements EditText.OnEditorActionListener {
|
||||||
private String password;
|
private String password;
|
||||||
|
|
||||||
|
|
|
@ -22,64 +22,55 @@
|
||||||
|
|
||||||
package org.shadowice.flocke.andotp.Activities;
|
package org.shadowice.flocke.andotp.Activities;
|
||||||
|
|
||||||
import android.app.KeyguardManager;
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import org.shadowice.flocke.andotp.R;
|
public abstract class BaseActivity extends ThemedActivity {
|
||||||
import org.shadowice.flocke.andotp.Utilities.Settings;
|
private ScreenOffReceiver screenOffReceiver;
|
||||||
|
private BroadcastReceivedCallback broadcastReceivedCallback;
|
||||||
import static org.shadowice.flocke.andotp.Utilities.Settings.AuthMethod;
|
|
||||||
|
|
||||||
public class BaseActivity extends AppCompatActivity {
|
|
||||||
private static final int INTENT_INTERNAL_AUTHENTICATE = 1;
|
|
||||||
|
|
||||||
public Settings settings;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
settings = new Settings(this);
|
|
||||||
|
|
||||||
String theme = settings.getTheme();
|
|
||||||
|
|
||||||
if (theme.equals("light")) {
|
|
||||||
setTheme(R.style.AppTheme_NoActionBar);
|
|
||||||
} else if (theme.equals("dark")) {
|
|
||||||
setTheme(R.style.AppTheme_Dark_NoActionBar);
|
|
||||||
}
|
|
||||||
|
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
}
|
|
||||||
|
|
||||||
public void authenticate() {
|
screenOffReceiver = new ScreenOffReceiver();
|
||||||
AuthMethod authMethod = settings.getAuthMethod();
|
registerReceiver(screenOffReceiver, screenOffReceiver.filter);
|
||||||
|
|
||||||
if (authMethod == AuthMethod.DEVICE) {
|
|
||||||
KeyguardManager km = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
|
|
||||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP && km.isKeyguardSecure()) {
|
|
||||||
Intent authIntent = km.createConfirmDeviceCredentialIntent(getString(R.string.dialog_title_auth), getString(R.string.dialog_msg_auth));
|
|
||||||
startActivityForResult(authIntent, INTENT_INTERNAL_AUTHENTICATE);
|
|
||||||
}
|
|
||||||
} else if (authMethod == AuthMethod.PASSWORD || authMethod == AuthMethod.PIN) {
|
|
||||||
Intent authIntent = new Intent(this, AuthenticateActivity.class);
|
|
||||||
startActivityForResult(authIntent, INTENT_INTERNAL_AUTHENTICATE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
|
protected void onDestroy() {
|
||||||
super.onActivityResult(requestCode, resultCode, intent);
|
unregisterReceiver(screenOffReceiver);
|
||||||
|
|
||||||
if (requestCode == INTENT_INTERNAL_AUTHENTICATE && resultCode != RESULT_OK) {
|
super.onDestroy();
|
||||||
Toast.makeText(getBaseContext(), R.string.toast_auth_failed, Toast.LENGTH_LONG).show();
|
}
|
||||||
|
|
||||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
|
private void destroyIfNotMain() {
|
||||||
finishAndRemoveTask();
|
if (getClass() != MainActivity.class)
|
||||||
} else {
|
finish();
|
||||||
finish();
|
}
|
||||||
|
|
||||||
|
public void setBroadcastCallback(BroadcastReceivedCallback cb) {
|
||||||
|
this.broadcastReceivedCallback = cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ScreenOffReceiver extends BroadcastReceiver {
|
||||||
|
public IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
|
||||||
|
if (broadcastReceivedCallback != null)
|
||||||
|
broadcastReceivedCallback.onReceivedScreenOff();
|
||||||
|
|
||||||
|
destroyIfNotMain();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface BroadcastReceivedCallback {
|
||||||
|
void onReceivedScreenOff();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ package org.shadowice.flocke.andotp.Activities;
|
||||||
|
|
||||||
import android.animation.ObjectAnimator;
|
import android.animation.ObjectAnimator;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
|
import android.app.KeyguardManager;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
@ -52,6 +53,7 @@ import android.widget.Toast;
|
||||||
import com.google.zxing.integration.android.IntentIntegrator;
|
import com.google.zxing.integration.android.IntentIntegrator;
|
||||||
import com.google.zxing.integration.android.IntentResult;
|
import com.google.zxing.integration.android.IntentResult;
|
||||||
|
|
||||||
|
import org.shadowice.flocke.andotp.Utilities.Settings;
|
||||||
import org.shadowice.flocke.andotp.View.EntriesCardAdapter;
|
import org.shadowice.flocke.andotp.View.EntriesCardAdapter;
|
||||||
import org.shadowice.flocke.andotp.Database.Entry;
|
import org.shadowice.flocke.andotp.Database.Entry;
|
||||||
import org.shadowice.flocke.andotp.View.FloatingActionMenu;
|
import org.shadowice.flocke.andotp.View.FloatingActionMenu;
|
||||||
|
@ -65,8 +67,9 @@ import static org.shadowice.flocke.andotp.Utilities.Settings.SortMode;
|
||||||
|
|
||||||
public class MainActivity extends BaseActivity
|
public class MainActivity extends BaseActivity
|
||||||
implements SharedPreferences.OnSharedPreferenceChangeListener {
|
implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
private static final int INTENT_INTERNAL_SETTINGS = 101;
|
private static final int INTENT_INTERNAL_AUTHENTICATE = 100;
|
||||||
private static final int INTENT_INTERNAL_BACKUP = 102;
|
private static final int INTENT_INTERNAL_SETTINGS = 101;
|
||||||
|
private static final int INTENT_INTERNAL_BACKUP = 102;
|
||||||
|
|
||||||
private EntriesCardAdapter adapter;
|
private EntriesCardAdapter adapter;
|
||||||
private FloatingActionMenu floatingActionMenu;
|
private FloatingActionMenu floatingActionMenu;
|
||||||
|
@ -74,6 +77,8 @@ public class MainActivity extends BaseActivity
|
||||||
private MenuItem sortMenu;
|
private MenuItem sortMenu;
|
||||||
private SimpleItemTouchHelperCallback touchHelperCallback;
|
private SimpleItemTouchHelperCallback touchHelperCallback;
|
||||||
|
|
||||||
|
private boolean requireAuthentication = false;
|
||||||
|
|
||||||
private Handler handler;
|
private Handler handler;
|
||||||
private Runnable handlerTask;
|
private Runnable handlerTask;
|
||||||
|
|
||||||
|
@ -149,6 +154,21 @@ public class MainActivity extends BaseActivity
|
||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void authenticate() {
|
||||||
|
Settings.AuthMethod authMethod = settings.getAuthMethod();
|
||||||
|
|
||||||
|
if (authMethod == Settings.AuthMethod.DEVICE) {
|
||||||
|
KeyguardManager km = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
|
||||||
|
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP && km.isKeyguardSecure()) {
|
||||||
|
Intent authIntent = km.createConfirmDeviceCredentialIntent(getString(R.string.dialog_title_auth), getString(R.string.dialog_msg_auth));
|
||||||
|
startActivityForResult(authIntent, INTENT_INTERNAL_AUTHENTICATE);
|
||||||
|
}
|
||||||
|
} else if (authMethod == Settings.AuthMethod.PASSWORD || authMethod == Settings.AuthMethod.PIN) {
|
||||||
|
Intent authIntent = new Intent(this, AuthenticateActivity.class);
|
||||||
|
startActivityForResult(authIntent, INTENT_INTERNAL_AUTHENTICATE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void restoreSortMode() {
|
private void restoreSortMode() {
|
||||||
if (settings != null && adapter != null && touchHelperCallback != null) {
|
if (settings != null && adapter != null && touchHelperCallback != null) {
|
||||||
SortMode mode = settings.getSortMode();
|
SortMode mode = settings.getSortMode();
|
||||||
|
@ -182,7 +202,14 @@ public class MainActivity extends BaseActivity
|
||||||
settings.registerPreferenceChangeListener(this);
|
settings.registerPreferenceChangeListener(this);
|
||||||
|
|
||||||
if (savedInstanceState == null)
|
if (savedInstanceState == null)
|
||||||
authenticate();
|
requireAuthentication = true;
|
||||||
|
|
||||||
|
setBroadcastCallback(new BroadcastReceivedCallback() {
|
||||||
|
@Override
|
||||||
|
public void onReceivedScreenOff() {
|
||||||
|
requireAuthentication = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (! settings.getFirstTimeWarningShown()) {
|
if (! settings.getFirstTimeWarningShown()) {
|
||||||
showFirstTimeWarning();
|
showFirstTimeWarning();
|
||||||
|
@ -279,6 +306,12 @@ public class MainActivity extends BaseActivity
|
||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
|
||||||
|
if (requireAuthentication) {
|
||||||
|
requireAuthentication = false;
|
||||||
|
authenticate();
|
||||||
|
}
|
||||||
|
|
||||||
startUpdater();
|
startUpdater();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -317,6 +350,18 @@ public class MainActivity extends BaseActivity
|
||||||
} else if (requestCode == INTENT_INTERNAL_BACKUP && resultCode == RESULT_OK) {
|
} else if (requestCode == INTENT_INTERNAL_BACKUP && resultCode == RESULT_OK) {
|
||||||
if (intent.getBooleanExtra("reload", false))
|
if (intent.getBooleanExtra("reload", false))
|
||||||
adapter.loadEntries();
|
adapter.loadEntries();
|
||||||
|
} else if (requestCode == INTENT_INTERNAL_AUTHENTICATE) {
|
||||||
|
if (resultCode != RESULT_OK) {
|
||||||
|
Toast.makeText(getBaseContext(), R.string.toast_auth_failed, Toast.LENGTH_LONG).show();
|
||||||
|
|
||||||
|
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
finishAndRemoveTask();
|
||||||
|
} else {
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
requireAuthentication = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Jakob Nixdorf
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.shadowice.flocke.andotp.Activities;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
|
||||||
|
import org.shadowice.flocke.andotp.R;
|
||||||
|
import org.shadowice.flocke.andotp.Utilities.Settings;
|
||||||
|
|
||||||
|
public abstract class ThemedActivity extends AppCompatActivity {
|
||||||
|
public Settings settings;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
settings = new Settings(this);
|
||||||
|
|
||||||
|
String theme = settings.getTheme();
|
||||||
|
|
||||||
|
if (theme.equals("light")) {
|
||||||
|
setTheme(R.style.AppTheme_NoActionBar);
|
||||||
|
} else if (theme.equals("dark")) {
|
||||||
|
setTheme(R.style.AppTheme_Dark_NoActionBar);
|
||||||
|
}
|
||||||
|
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue