Request permissions at runtime if needed

This commit is contained in:
Alexander Bakker 2017-12-13 19:00:58 +01:00
parent 03d0eb01f4
commit 181cdc4c2e
2 changed files with 127 additions and 38 deletions

View file

@ -1,5 +1,6 @@
package me.impy.aegis; package me.impy.aegis;
import android.Manifest;
import android.content.ClipData; import android.content.ClipData;
import android.content.ClipboardManager; import android.content.ClipboardManager;
import android.content.Context; import android.content.Context;
@ -37,11 +38,13 @@ import java.util.List;
import me.impy.aegis.crypto.MasterKey; import me.impy.aegis.crypto.MasterKey;
import me.impy.aegis.db.DatabaseEntry; import me.impy.aegis.db.DatabaseEntry;
import me.impy.aegis.db.DatabaseManager; import me.impy.aegis.db.DatabaseManager;
import me.impy.aegis.helpers.PermissionHelper;
import me.impy.aegis.importers.DatabaseImporter; import me.impy.aegis.importers.DatabaseImporter;
import me.impy.aegis.helpers.SimpleItemTouchHelperCallback; import me.impy.aegis.helpers.SimpleItemTouchHelperCallback;
import me.impy.aegis.util.ByteInputStream; import me.impy.aegis.util.ByteInputStream;
public class MainActivity extends AppCompatActivity implements KeyProfileAdapter.Listener { public class MainActivity extends AppCompatActivity implements KeyProfileAdapter.Listener {
// activity request codes
private static final int CODE_GET_KEYINFO = 0; private static final int CODE_GET_KEYINFO = 0;
private static final int CODE_ADD_KEYINFO = 1; private static final int CODE_ADD_KEYINFO = 1;
private static final int CODE_DO_INTRO = 2; private static final int CODE_DO_INTRO = 2;
@ -49,6 +52,11 @@ public class MainActivity extends AppCompatActivity implements KeyProfileAdapter
private static final int CODE_IMPORT = 4; private static final int CODE_IMPORT = 4;
private static final int CODE_PREFERENCES = 5; private static final int CODE_PREFERENCES = 5;
// permission request codes
private static final int CODE_PERM_EXPORT = 0;
private static final int CODE_PERM_IMPORT = 1;
private static final int CODE_PERM_CAMERA = 2;
private KeyProfileAdapter _keyProfileAdapter; private KeyProfileAdapter _keyProfileAdapter;
private DatabaseManager _db; private DatabaseManager _db;
@ -103,8 +111,7 @@ public class MainActivity extends AppCompatActivity implements KeyProfileAdapter
FloatingActionButton fab = findViewById(R.id.fab); FloatingActionButton fab = findViewById(R.id.fab);
fab.setEnabled(true); fab.setEnabled(true);
fab.setOnClickListener(view -> { fab.setOnClickListener(view -> {
Intent scannerActivity = new Intent(getApplicationContext(), ScannerActivity.class); onGetKeyInfo();
startActivityForResult(scannerActivity, CODE_GET_KEYINFO);
}); });
RecyclerView rvKeyProfiles = findViewById(R.id.rvKeyProfiles); RecyclerView rvKeyProfiles = findViewById(R.id.rvKeyProfiles);
@ -146,6 +153,26 @@ public class MainActivity extends AppCompatActivity implements KeyProfileAdapter
} }
} }
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (!PermissionHelper.checkResults(grantResults)) {
Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show();
return;
}
switch (requestCode) {
case CODE_PERM_EXPORT:
onExport();
break;
case CODE_PERM_IMPORT:
onImport();
break;
case CODE_PERM_CAMERA:
onGetKeyInfo();
break;
}
}
private void onPreferencesResult(int resultCode, Intent data) { private void onPreferencesResult(int resultCode, Intent data) {
// refresh the entire key profile list if needed // refresh the entire key profile list if needed
if (data.getBooleanExtra("needsRefresh", false)) { if (data.getBooleanExtra("needsRefresh", false)) {
@ -156,6 +183,16 @@ public class MainActivity extends AppCompatActivity implements KeyProfileAdapter
int action = data.getIntExtra("action", -1); int action = data.getIntExtra("action", -1);
switch (action) { switch (action) {
case PreferencesActivity.ACTION_EXPORT: case PreferencesActivity.ACTION_EXPORT:
onExport();
break;
}
}
private void onExport() {
if (!PermissionHelper.request(this, CODE_PERM_EXPORT, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
return;
}
// TODO: create a custom layout to show a message AND a checkbox // TODO: create a custom layout to show a message AND a checkbox
final boolean[] checked = {true}; final boolean[] checked = {true};
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this) AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this)
@ -189,8 +226,12 @@ public class MainActivity extends AppCompatActivity implements KeyProfileAdapter
builder.setMessage("This action will export the database out of Android's private storage."); builder.setMessage("This action will export the database out of Android's private storage.");
} }
builder.show(); builder.show();
break;
} }
private void onImport() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
startActivityForResult(intent, CODE_IMPORT);
} }
private void onImportResult(int resultCode, Intent data) { private void onImportResult(int resultCode, Intent data) {
@ -251,6 +292,15 @@ public class MainActivity extends AppCompatActivity implements KeyProfileAdapter
saveDatabase(); saveDatabase();
} }
private void onGetKeyInfo() {
if (!PermissionHelper.request(this, CODE_PERM_CAMERA, Manifest.permission.CAMERA)) {
return;
}
Intent scannerActivity = new Intent(getApplicationContext(), ScannerActivity.class);
startActivityForResult(scannerActivity, CODE_GET_KEYINFO);
}
private void onGetKeyInfoResult(int resultCode, Intent data) { private void onGetKeyInfoResult(int resultCode, Intent data) {
if (resultCode == RESULT_OK) { if (resultCode == RESULT_OK) {
KeyProfile keyProfile = (KeyProfile)data.getSerializableExtra("KeyProfile"); KeyProfile keyProfile = (KeyProfile)data.getSerializableExtra("KeyProfile");
@ -420,9 +470,9 @@ public class MainActivity extends AppCompatActivity implements KeyProfileAdapter
startActivityForResult(preferencesActivity, CODE_PREFERENCES); startActivityForResult(preferencesActivity, CODE_PREFERENCES);
return true; return true;
case R.id.action_import: case R.id.action_import:
Intent intent = new Intent(Intent.ACTION_GET_CONTENT); if (PermissionHelper.request(this, CODE_PERM_IMPORT, Manifest.permission.CAMERA)) {
intent.setType("*/*"); onImport();
startActivityForResult(intent, CODE_IMPORT); }
return true; return true;
case R.id.action_lock: case R.id.action_lock:
// TODO: properly close the database // TODO: properly close the database

View file

@ -0,0 +1,39 @@
package me.impy.aegis.helpers;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.support.v4.app.ActivityCompat;
import java.util.ArrayList;
import java.util.List;
public class PermissionHelper {
private PermissionHelper() {
}
public static boolean request(Activity activity, int requestCode, String... perms) {
List<String> deniedPerms = new ArrayList<>();
for (String permission : perms) {
if (ActivityCompat.checkSelfPermission(activity, permission) == PackageManager.PERMISSION_DENIED) {
deniedPerms.add(permission);
}
}
int size = deniedPerms.size();
if (size > 0) {
String[] array = new String[size];
ActivityCompat.requestPermissions(activity, deniedPerms.toArray(array), requestCode);
}
return size == 0;
}
public static boolean checkResults(int[] grantResults) {
for (int result : grantResults) {
if (result != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return true;
}
}