From 457aeeabf39a6e4c8a80c917b8101fd5658a41a7 Mon Sep 17 00:00:00 2001 From: Siddharth Malladi Date: Thu, 14 Dec 2023 10:02:54 -0800 Subject: [PATCH 01/10] Revamp UI: Add bottom toolbar, update settings, modify main screen, rename app --- .../org/phenoapps/verify/MainActivity.java | 344 ++++++------------ .../phenoapps/verify/SettingsActivity.java | 4 + .../phenoapps/verify/SettingsFragment.java | 91 +++++ .../java/org/phenoapps/verify/UriHandler.java | 2 +- app/src/main/res/drawable-anydpi/ic_home.xml | 16 + app/src/main/res/drawable-hdpi/ic_home.png | Bin 0 -> 355 bytes .../res/drawable-hdpi/ic_import_white.png | Bin 0 -> 4427 bytes .../main/res/drawable-hdpi/ic_settings.png | Bin 561 -> 4511 bytes app/src/main/res/drawable-mdpi/ic_home.png | Bin 0 -> 253 bytes .../res/drawable-mdpi/ic_import_white.png | Bin 0 -> 4427 bytes .../main/res/drawable-mdpi/ic_settings.png | Bin 383 -> 4511 bytes app/src/main/res/drawable-xhdpi/ic_home.png | Bin 0 -> 432 bytes .../res/drawable-xhdpi/ic_import_white.png | Bin 0 -> 4427 bytes .../main/res/drawable-xhdpi/ic_settings.png | Bin 677 -> 4511 bytes app/src/main/res/drawable-xxhdpi/ic_home.png | Bin 0 -> 627 bytes .../res/drawable-xxhdpi/ic_import_white.png | Bin 0 -> 4427 bytes .../main/res/drawable-xxhdpi/ic_settings.png | Bin 1031 -> 4511 bytes .../main/res/layout-land/activity_main.xml | 26 +- .../main/res/layout-xlarge/activity_main.xml | 26 +- app/src/main/res/layout/activity_main.xml | 62 ++-- .../res/menu/activity_main_bottom_toolbar.xml | 23 ++ .../main/res/menu/activity_main_toolbar.xml | 14 +- app/src/main/res/xml/preferences.xml | 9 + 23 files changed, 345 insertions(+), 272 deletions(-) create mode 100644 app/src/main/res/drawable-anydpi/ic_home.xml create mode 100644 app/src/main/res/drawable-hdpi/ic_home.png create mode 100644 app/src/main/res/drawable-hdpi/ic_import_white.png create mode 100644 app/src/main/res/drawable-mdpi/ic_home.png create mode 100644 app/src/main/res/drawable-mdpi/ic_import_white.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_home.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_import_white.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_home.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_import_white.png create mode 100644 app/src/main/res/menu/activity_main_bottom_toolbar.xml diff --git a/app/src/main/java/org/phenoapps/verify/MainActivity.java b/app/src/main/java/org/phenoapps/verify/MainActivity.java index c9d424b..f98a6e9 100644 --- a/app/src/main/java/org/phenoapps/verify/MainActivity.java +++ b/app/src/main/java/org/phenoapps/verify/MainActivity.java @@ -19,6 +19,9 @@ import androidx.annotation.NonNull; import com.google.android.material.navigation.NavigationView; + +import androidx.appcompat.widget.ActionMenuView; +import androidx.appcompat.widget.Toolbar; import androidx.core.app.ActivityCompat; import androidx.core.view.GravityCompat; import androidx.drawerlayout.widget.DrawerLayout; @@ -34,6 +37,7 @@ import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; +import android.view.ViewGroup; import android.view.inputmethod.InputMethodManager; import android.widget.AbsListView; import android.widget.AdapterView; @@ -72,9 +76,6 @@ public class MainActivity extends AppCompatActivity { private SparseArray mIds; - //Verify UI variables - private ActionBarDrawerToggle mDrawerToggle; - //global variable to track matching order private int mMatchingOrder; @@ -86,6 +87,8 @@ public class MainActivity extends AppCompatActivity { private String mFileName = ""; + private Toolbar navigationToolBar; + @Override protected void onCreate(Bundle savedInstanceState) { @@ -97,29 +100,29 @@ protected void onCreate(Bundle savedInstanceState) { SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); - final View auxInfo = findViewById(R.id.auxScrollView); - final View auxValue = findViewById(R.id.auxValueView); +final View auxInfo = findViewById(R.id.auxScrollView); +final View auxValue = findViewById(R.id.auxValueView); if (sharedPref.getBoolean(SettingsActivity.AUX_INFO, false)) { - auxInfo.setVisibility(View.VISIBLE); - auxValue.setVisibility(View.VISIBLE); +auxInfo.setVisibility(View.VISIBLE); +auxValue.setVisibility(View.VISIBLE); } else { - auxInfo.setVisibility(View.GONE); - auxValue.setVisibility(View.GONE); - } +auxInfo.setVisibility(View.GONE); +auxValue.setVisibility(View.GONE); +} mPrefListener = new SharedPreferences.OnSharedPreferenceChangeListener() { @Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) { - if (sharedPreferences.getBoolean(SettingsActivity.AUX_INFO, false)) { - auxInfo.setVisibility(View.VISIBLE); - auxValue.setVisibility(View.VISIBLE); - } else { - auxInfo.setVisibility(View.GONE); - auxValue.setVisibility(View.GONE); - } +if (sharedPreferences.getBoolean(SettingsActivity.AUX_INFO, false)) { +auxInfo.setVisibility(View.VISIBLE); +auxValue.setVisibility(View.VISIBLE); +} else { +auxInfo.setVisibility(View.GONE); +auxValue.setVisibility(View.GONE); +} } }; @@ -208,18 +211,11 @@ private void prepareStatements() { private void initializeUIVariables() { if (getSupportActionBar() != null){ - getSupportActionBar().setTitle(null); + getSupportActionBar().setTitle("CheckList"); getSupportActionBar().getThemedContext(); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setHomeButtonEnabled(true); } - final NavigationView nvDrawer = (NavigationView) findViewById(R.id.nvView); - - // Setup drawer view - setupDrawerContent(nvDrawer); - setupDrawer(); - final EditText scannerTextView = ((EditText) findViewById(R.id.scannerTextView)); scannerTextView.setSelectAllOnFocus(true); scannerTextView.setOnKeyListener(new View.OnKeyListener() { @@ -237,25 +233,25 @@ public boolean onKey(View v, int keyCode, KeyEvent event) { ListView idTable = ((ListView) findViewById(R.id.idTable)); idTable.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE); - idTable.setOnItemClickListener(new AdapterView.OnItemClickListener() { +idTable.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView parent, View view, int position, long id) { - scannerTextView.setText(((TextView) view).getText().toString()); +scannerTextView.setText(((TextView) view).getText().toString()); scannerTextView.setSelection(scannerTextView.getText().length()); scannerTextView.requestFocus(); scannerTextView.selectAll(); checkScannedItem(); - } + } }); - idTable.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { - @Override - public boolean onItemLongClick(AdapterView parent, View view, int position, long id) { - //get app settings - insertNoteIntoDb(((TextView) view).getText().toString()); - return true; - } +idTable.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { +@Override +public boolean onItemLongClick(AdapterView parent, View view, int position, long id) { +//get app settings +insertNoteIntoDb(((TextView) view).getText().toString()); +return true; +} }); TextView valueView = (TextView) findViewById(R.id.valueView); @@ -273,7 +269,7 @@ private synchronized void checkScannedItem() { SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(MainActivity.this); int scanMode = Integer.valueOf(sharedPref.getString(SettingsActivity.SCAN_MODE_LIST, "-1")); - boolean displayAux = sharedPref.getBoolean(SettingsActivity.AUX_INFO, true); +boolean displayAux = sharedPref.getBoolean(SettingsActivity.AUX_INFO, true); String scannedId = ((EditText) findViewById(org.phenoapps.verify.R.id.scannerTextView)) .getText().toString(); @@ -318,10 +314,10 @@ private synchronized void checkScannedItem() { } } } - cursor.close(); - ((TextView) findViewById(org.phenoapps.verify.R.id.valueView)).setText(values.toString()); - ((TextView) findViewById(R.id.auxValueView)).setText(auxValues.toString()); - ((EditText) findViewById(R.id.scannerTextView)).setText(""); + cursor.close(); +((TextView) findViewById(org.phenoapps.verify.R.id.valueView)).setText(values.toString()); +((TextView) findViewById(R.id.auxValueView)).setText(auxValues.toString()); +((EditText) findViewById(R.id.scannerTextView)).setText(""); } else { if (scanMode != 2) { ringNotification(false); @@ -808,6 +804,19 @@ final public boolean onCreateOptionsMenu(Menu m) { final MenuInflater inflater = getMenuInflater(); inflater.inflate(org.phenoapps.verify.R.menu.activity_main_toolbar, m); + + ActionMenuView bottomToolBar = (ActionMenuView) findViewById(R.id.bottom_toolbar); + Menu bottomMenu = bottomToolBar.getMenu(); + inflater.inflate(R.menu.activity_main_bottom_toolbar, bottomMenu); + + for (int i = 0; i < bottomMenu.size(); i++) { + bottomMenu.getItem(i).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + return onOptionsItemSelected(item); + } + }); + } return true; } @@ -815,25 +824,81 @@ final public boolean onCreateOptionsMenu(Menu m) { final public boolean onOptionsItemSelected(MenuItem item) { DrawerLayout dl = (DrawerLayout) findViewById(R.id.drawer_layout); int actionCamera = R.id.action_camera; - int actionCompare = R.id.action_compare; - if (mDrawerToggle.onOptionsItemSelected(item)) { - return true; - } + int actionImport = R.id.action_import; + int actionHome = R.id.Home; + int actionCompare = R.id.Compare; + int actionSettings = R.id.Settings; + + if (item.getItemId() == actionImport){ + final SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(MainActivity.this); + final int scanMode = Integer.valueOf(sharedPref.getString(SettingsActivity.SCAN_MODE_LIST, "-1")); + final Intent i; + File verifyDirectory = new File(getExternalFilesDir(null), "/Verify"); + + File[] files = verifyDirectory.listFiles(); + + + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle("Select files from?"); + builder.setPositiveButton("Storage", + new DialogInterface.OnClickListener() + { + public void onClick(DialogInterface dialog, int id) + { + Intent i; + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) { + i = new Intent(Intent.ACTION_OPEN_DOCUMENT); + }else{ + i = new Intent(Intent.ACTION_GET_CONTENT); + } + i.setType("*/*"); + startActivityForResult(Intent.createChooser(i, "Choose file to import."), VerifyConstants.DEFAULT_CONTENT_REQ); + } + }); + + builder.setNegativeButton("Verify Directory", + new DialogInterface.OnClickListener() + { + public void onClick(DialogInterface dialog, int id) + { + + AlertDialog.Builder fileBuilder = new AlertDialog.Builder(MainActivity.this); + fileBuilder.setTitle("Select the sample file"); + final int[] checkedItem = {-1}; + String[] listItems = verifyDirectory.list(); + fileBuilder.setSingleChoiceItems(listItems, checkedItem[0],(fileDialog, which) -> { + checkedItem[0] = which; + + Intent i = new Intent(MainActivity.this, LoaderDBActivity.class); + i.setData(Uri.fromFile(files[which])); + startActivityForResult(i, VerifyConstants.LOADER_INTENT_REQ); + fileDialog.dismiss(); + }); + + fileBuilder.show(); - if (item.getItemId() == android.R.id.home){ + } + }); + builder.show(); + } else if (item.getItemId() == android.R.id.home){ dl.openDrawer(GravityCompat.START); } - else if(item.getItemId() == actionCamera){ - final Intent cameraIntent = new Intent(this, ScanActivity.class); - startActivityForResult(cameraIntent, VerifyConstants.CAMERA_INTENT_REQ); + else if (item.getItemId() == actionHome){ + } - else if(item.getItemId() == actionCompare){ + else if ( item.getItemId() == actionCompare) { final Intent compareIntent = new Intent(MainActivity.this, CompareActivity.class); runOnUiThread(new Runnable() { @Override public void run() { startActivity(compareIntent); } }); + } else if (item.getItemId() == actionSettings) { + final Intent settingsIntent = new Intent(this, SettingsActivity.class); + startActivityForResult(settingsIntent, VerifyConstants.SETTINGS_INTENT_REQ); + } else if(item.getItemId() == actionCamera){ + final Intent cameraIntent = new Intent(this, ScanActivity.class); + startActivityForResult(cameraIntent, VerifyConstants.CAMERA_INTENT_REQ); } else{ return super.onOptionsItemSelected(item); @@ -912,131 +977,23 @@ final protected void onActivityResult(int requestCode, int resultCode, Intent in private void buildListView() { ListView idTable = (ListView) findViewById(org.phenoapps.verify.R.id.idTable); - ArrayAdapter idAdapter = - new ArrayAdapter<>(this, org.phenoapps.verify.R.layout.row); +ArrayAdapter idAdapter = +new ArrayAdapter<>(this, org.phenoapps.verify.R.layout.row); int size = mIds.size(); for (int i = 0; i < size; i++) { - idAdapter.add(this.mIds.get(this.mIds.keyAt(i))); +idAdapter.add(this.mIds.get(this.mIds.keyAt(i))); } - idTable.setAdapter(idAdapter); +idTable.setAdapter(idAdapter); } private void clearListView() { ListView idTable = (ListView) findViewById(org.phenoapps.verify.R.id.idTable); - final ArrayAdapter adapter = - new ArrayAdapter<>(this, org.phenoapps.verify.R.layout.row); +final ArrayAdapter adapter = +new ArrayAdapter<>(this, org.phenoapps.verify.R.layout.row); idTable.setAdapter(adapter); - adapter.notifyDataSetChanged(); - } - - private void setupDrawer() { - - DrawerLayout dl = (DrawerLayout) findViewById(org.phenoapps.verify.R.id.drawer_layout); - mDrawerToggle = new ActionBarDrawerToggle(this, dl, - org.phenoapps.verify.R.string.drawer_open, org.phenoapps.verify.R.string.drawer_close) { - - public void onDrawerOpened(View drawerView) { - View view = MainActivity.this.getCurrentFocus(); - if (view != null) { - InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); - imm.hideSoftInputFromWindow(view.getWindowToken(), 0); - } - } - - public void onDrawerClosed(View view) { - } - - }; - - mDrawerToggle.setDrawerIndicatorEnabled(true); - dl.addDrawerListener(mDrawerToggle); - } - - private void setupDrawerContent(NavigationView navigationView) { - navigationView.setNavigationItemSelectedListener( - new NavigationView.OnNavigationItemSelectedListener() { - @Override - public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) { - selectDrawerItem(menuItem); - return true; - } - }); - } - - private void selectDrawerItem(MenuItem menuItem) { - int itemId = menuItem.getItemId(); - // constants like id in R class are no longer final, thus can't use switch here - - if (itemId == R.id.nav_import){ - final SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(MainActivity.this); - final int scanMode = Integer.valueOf(sharedPref.getString(SettingsActivity.SCAN_MODE_LIST, "-1")); - final Intent i; - File verifyDirectory = new File(getExternalFilesDir(null), "/Verify"); - - File[] files = verifyDirectory.listFiles(); - - - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle("Select files from?"); - builder.setPositiveButton("Storage", - new DialogInterface.OnClickListener() - { - public void onClick(DialogInterface dialog, int id) - { - Intent i; - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) { - i = new Intent(Intent.ACTION_OPEN_DOCUMENT); - }else{ - i = new Intent(Intent.ACTION_GET_CONTENT); - } - i.setType("*/*"); - startActivityForResult(Intent.createChooser(i, "Choose file to import."), VerifyConstants.DEFAULT_CONTENT_REQ); - } - }); - - builder.setNegativeButton("Verify Directory", - new DialogInterface.OnClickListener() - { - public void onClick(DialogInterface dialog, int id) - { - - AlertDialog.Builder fileBuilder = new AlertDialog.Builder(MainActivity.this); - fileBuilder.setTitle("Select the sample file"); - final int[] checkedItem = {-1}; - String[] listItems = verifyDirectory.list(); - fileBuilder.setSingleChoiceItems(listItems, checkedItem[0],(fileDialog, which) -> { - checkedItem[0] = which; - - Intent i = new Intent(MainActivity.this, LoaderDBActivity.class); - i.setData(Uri.fromFile(files[which])); - startActivityForResult(i, VerifyConstants.LOADER_INTENT_REQ); - fileDialog.dismiss(); - }); - - fileBuilder.show(); - - } - }); - builder.show(); - } else if (itemId == R.id.nav_settings) { - final Intent settingsIntent = new Intent(this, SettingsActivity.class); - startActivityForResult(settingsIntent, VerifyConstants.SETTINGS_INTENT_REQ); - } else if (itemId == R.id.nav_export) { - askUserExportFileName(); - } else if (itemId == R.id.nav_about) { - showAboutDialog(); - } else if (itemId == R.id.nav_intro) { - final Intent intro_intent = new Intent(MainActivity.this, IntroActivity.class); - runOnUiThread(new Runnable() { - @Override public void run() { - startActivity(intro_intent); - } - }); - } - DrawerLayout dl = (DrawerLayout) findViewById(org.phenoapps.verify.R.id.drawer_layout); - dl.closeDrawers(); +adapter.notifyDataSetChanged(); } private void showPairDialog() { @@ -1065,73 +1022,14 @@ public void onClick(DialogInterface dialogInterface, int i) { builder.show(); } - private void showAboutDialog() - { - android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(this); - { - android.view.View personView = this.getLayoutInflater().inflate( - org.phenoapps.verify.R.layout.about, new android.widget.LinearLayout(this), - false); - - { - assert personView != null; - android.widget.TextView versionTextView = (android.widget.TextView) - personView.findViewById(org.phenoapps.verify.R.id.tvVersion); - try - { - android.content.pm.PackageInfo packageInfo = - this.getPackageManager().getPackageInfo(this.getPackageName(), 0); - assert packageInfo != null; - assert versionTextView != null; - versionTextView.setText(this.getResources().getString( - org.phenoapps.verify.R.string.versiontitle) + - ' ' + packageInfo.versionName); - } - catch (android.content.pm.PackageManager.NameNotFoundException e) - { e.printStackTrace(); } - versionTextView.setOnClickListener(new android.view.View.OnClickListener() - { - @java.lang.Override - public void onClick(android.view.View v) - { MainActivity.this.showChangeLog(); } - }); - } - - builder.setCancelable(true); - builder.setTitle (this.getResources().getString( - org.phenoapps.verify.R.string.about)); - builder.setView(personView); - } - - builder.setNegativeButton( - this.getResources().getString(org.phenoapps.verify.R.string.ok), - new android.content.DialogInterface.OnClickListener() - { - @java.lang.Override - public void onClick(android.content.DialogInterface dialog, int which) - { - assert dialog != null; - dialog.dismiss(); - } - }); - - builder.show(); - } - - private void showChangeLog() { - - } - @Override final protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); - mDrawerToggle.syncState(); } @Override final public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); - mDrawerToggle.onConfigurationChanged(newConfig); } private void launchIntro() { diff --git a/app/src/main/java/org/phenoapps/verify/SettingsActivity.java b/app/src/main/java/org/phenoapps/verify/SettingsActivity.java index fb5a18f..f12ff6e 100644 --- a/app/src/main/java/org/phenoapps/verify/SettingsActivity.java +++ b/app/src/main/java/org/phenoapps/verify/SettingsActivity.java @@ -8,6 +8,10 @@ public class SettingsActivity extends AppCompatActivity { public static String FILE_NAME = "org.phenoapps.verify.FILE_NAME"; + public static String INTRO_BUTTON = "org.phenoapps.verify.INTRO"; + + public static String ABOUT_BUTTON = "org.phenoapps.verify.ABOUT"; + public static String SCAN_MODE_LIST = "org.phenoapps.verify.SCAN_MODE"; public static String AUDIO_ENABLED = "org.phenoapps.verify.AUDIO_ENABLED"; public static String TUTORIAL_MODE = "org.phenoapps.verify.TUTORIAL_MODE"; diff --git a/app/src/main/java/org/phenoapps/verify/SettingsFragment.java b/app/src/main/java/org/phenoapps/verify/SettingsFragment.java index 577aa32..89c8970 100644 --- a/app/src/main/java/org/phenoapps/verify/SettingsFragment.java +++ b/app/src/main/java/org/phenoapps/verify/SettingsFragment.java @@ -1,14 +1,78 @@ package org.phenoapps.verify; +import android.content.Context; +import android.content.Intent; import android.content.SharedPreferences; +import android.os.Build; import android.os.Bundle; import android.preference.ListPreference; import android.preference.Preference; import android.preference.PreferenceFragment; import android.widget.Toast; +import java.util.prefs.Preferences; + public class SettingsFragment extends PreferenceFragment { + + private void showChangeLog() { + + } + private void showAboutDialog(Context ctx) + { + android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(ctx); + { + android.view.View personView = null; + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { + personView = getLayoutInflater().inflate( + R.layout.about, new android.widget.LinearLayout(ctx), + false); + } + { + assert personView != null; + android.widget.TextView versionTextView = (android.widget.TextView) + personView.findViewById(org.phenoapps.verify.R.id.tvVersion); + try + { + android.content.pm.PackageInfo packageInfo = + ctx.getPackageManager().getPackageInfo(ctx.getPackageName(), 0); + assert packageInfo != null; + assert versionTextView != null; + versionTextView.setText(this.getResources().getString( + org.phenoapps.verify.R.string.versiontitle) + + ' ' + packageInfo.versionName); + } + catch (android.content.pm.PackageManager.NameNotFoundException e) + { e.printStackTrace(); } + versionTextView.setOnClickListener(new android.view.View.OnClickListener() + { + @java.lang.Override + public void onClick(android.view.View v) + { showChangeLog(); } + }); + } + + builder.setCancelable(true); + builder.setTitle (this.getResources().getString( + org.phenoapps.verify.R.string.about)); + builder.setView(personView); + } + + builder.setNegativeButton( + this.getResources().getString(org.phenoapps.verify.R.string.ok), + new android.content.DialogInterface.OnClickListener() + { + @java.lang.Override + public void onClick(android.content.DialogInterface dialog, int which) + { + assert dialog != null; + dialog.dismiss(); + } + }); + + builder.show(); + } + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -17,7 +81,34 @@ public void onCreate(Bundle savedInstanceState) { final SharedPreferences sharedPrefs = super.getPreferenceManager().getSharedPreferences(); ListPreference mode = (ListPreference) findPreference(SettingsActivity.SCAN_MODE_LIST); + Preference introButton = (Preference) findPreference(SettingsActivity.INTRO_BUTTON); + Preference aboutButton = (Preference) findPreference(SettingsActivity.ABOUT_BUTTON); + aboutButton.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + showAboutDialog(getContext()); + } + return true; + } + }); + + introButton.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { + final Intent intro_intent = new Intent(getContext(), IntroActivity.class); + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + startActivity(intro_intent); + } + }); + } + return true; + } + }); mode.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { //check if Pair mode is chosen, if it's disabled then show a message and switch //back to default mode. diff --git a/app/src/main/java/org/phenoapps/verify/UriHandler.java b/app/src/main/java/org/phenoapps/verify/UriHandler.java index 51c7d5f..851c11c 100644 --- a/app/src/main/java/org/phenoapps/verify/UriHandler.java +++ b/app/src/main/java/org/phenoapps/verify/UriHandler.java @@ -55,7 +55,7 @@ public static String getFileName(@NonNull Context context, Uri uri) { return fileName; } -//test + /** * Returns the effective file name from the provided Uri. * @param fileName diff --git a/app/src/main/res/drawable-anydpi/ic_home.xml b/app/src/main/res/drawable-anydpi/ic_home.xml new file mode 100644 index 0000000..3eb8fe0 --- /dev/null +++ b/app/src/main/res/drawable-anydpi/ic_home.xml @@ -0,0 +1,16 @@ + + + + + diff --git a/app/src/main/res/drawable-hdpi/ic_home.png b/app/src/main/res/drawable-hdpi/ic_home.png new file mode 100644 index 0000000000000000000000000000000000000000..bfbbd81b83105cbc3ef8be432f545087686b4e34 GIT binary patch literal 355 zcmV-p0i6DcP)~RN!c(+cMusjGQdde8!8@6=z$jdlIgy6X-<4C~)@3ba_ zy^9h|#(TkqkO5eV@J+nh9rg(#7@vT(2=$SHQ}$~l7@mP#gjL1vUa;>@g3$*Hi zk1_k#5)7_{aZ{$8Q%P976K0{f=e(`L!hF?^_>6!002ovPDHLkV1g_o Bq#6JK literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/ic_import_white.png b/app/src/main/res/drawable-hdpi/ic_import_white.png new file mode 100644 index 0000000000000000000000000000000000000000..f90b07ad7594e9ac654b0fd7c63b9f4538cf07e6 GIT binary patch literal 4427 zcmeHKdr%X19$%uK$sl z&F+35pWpZU`F?-j*Sf6%w8bok^$K3 z<5|wdz+$PFfteu3LQwF6+jeo{NmTa3!>I{v-g9l&QmwQ6>)%@LGQVRtRK2bj$DQph zZ9Pj>TB_g4EN;-e@Sf$Gr;5$0`(4w*^chiE56g(?Lz8Eps4Lw4bZ^JZuHP@sSI&Df z!Etnob>8xd4d9`qhv-#WdeGrv0t zy$#cMD<45|zuMp#vn$D}eP1I^{bXO>ug}lzz4XtFCy{rrygL1u=gL1IC}IO=G}b{2c4X~`d^6-(=nMcf3PqSkbj_5 zI+oZ_`(bMF^;yN8TU*iEjwRcha|BuRY)ABD(@T5b-GI4H6@6nlu;tyJ!<#FUuOBa3+w|?4&V-e>Z(hdF^p->Va^IF473z;b-vv3)Uj^2M1jW0RB+WY* zWzg*fjR!$#=|L|^6*D62V4R%CAiv$xDu+4RAYY=fqE@ewDdNm!J|?d$$4-?MQ+isS zJ|`wENB{sgBa(2??eYjj&>#=t65v@9BXT%oA{HCu1y&nuuqnOMR#v>*Vg`lYcf3M%?3Z+9+2;*Yhz*GRMs)j9@WwF`@JR}O7 zoZB1n0%Q-f6ghT~tYNW9nov4J0|D*>xWlaba}OBslZkD?f(&}cO}g<7k3DD;eqRp1P*V=y&^(>l!%D2qoBNe{(HPyk%X0US!F!L=Ch zA!&+HsC8Oa;ZSL51*)NNoYk=y%VI+y7Wp{Pm85HER1y>opmel`!cZ-xz%U(%Mu*Z0 z(xFBH6pJ|+N~6PYT?mS%i21zFO@eZAZqmshUXL@RkO(K{+AIb+rbGuNHWw+fz`-D2 z$a(z1L4}=jGkGE@v8mFbDh;YpYqU6u>s0DNqkP6EfKHS!Rj3m0(@13@Kr(<>QtDFx z5b^-I5Jn$EioDOx^Dcv23JI1x2h>)uooG@dO{B;GP!z)n6-J<#U4;`GHK9_apc(=n zV$ahYTl&AOrOgAU^_ASr31I!wkf?7*Le#A*y$Y98j z0e*clFucGlLTPna)wAcKq072uYNLK_@QyT|_ zQKH3~8Fgbqq%1C0-?3&J5Z$ww=Guc7ZeGluv>u(1(e~oi-X$dn6mj3^!ua#kYW_H* zvFm>IFD=z2D_1AYH_fj4s_^Bph0|`x{?ztdvOoSB6!E0-X2+$T=w;`H{cuJl6cIT_ z7F+*a)S>H3Z29lm(+~W{y!6n{6uG>k`?tQWfBm5PY-f8D{D)&_oEZx$Ce^%YzgnL< zg=_Gw*yRtTXjXplDDv|&jzIEr`E}#OhjYHZGId9LV|U8I#{En6?Q7XZ4-#?~*Ux?$ z?N3eL(SGZrF4v-JF=da;_BZDiBL3v8a0KQ(2hS}|X&p+VI>z9we d4HB8O`k9{Yf}pRU`+&rlB{Rp=IB&(e{{r%cN#g(j literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/ic_settings.png b/app/src/main/res/drawable-hdpi/ic_settings.png index 4cb8e41bfb6a23af97eca06167002f9f3e2466e6..bda5e854555c9d00cfab623cc26b1e8c7d032800 100644 GIT binary patch literal 4511 zcmeHKeNYo;8V`aJ5oqL8RIs-$*H+YIlifg)m8g&)1Pn&xL(2KF*?kjM$OqZQ1pGiN z=VvP-*H#e~to67mj#aFPUvNNm^c=mj);p&37}TqCO0`gjyQ=lx4Tv!9%#AbG|H#Z{ z-}m|Wz0dP|pZA%4x0q5Af&wN7h(w|wL!v$vz7vHefN89 z$=&I@0*lX0%J-|={`UFch_HDbl5Tm8B4hfYp28B4oS758g0FaTepCIm^XCe>iyO~Q zjnMdp1XWFud@|-iWrwlQt_`&|ZrqLCVHeE0_uAv$tOzV@eT_)uQ^M+WCWB7*A|04S z<(e{WV)NYa)@6(0%RUHRDajY7?wz@Lt9r%wt){781k{qde*42nI_+^@cz zbUbNwN{r>NBe(qe^ij{#&rjbw-bj38c~iR}{EZ3QrX1nrGj>n@Ze0HSoBZX_|GzZ;O(!rnA|y5rEZlG5VqkCX4DUP>Po zadE^a*O4=8AIES-*!Fd`Ug?_<604}a=lj?yf6rsori_xwb(eHq#ZUH#W>7B=CL_p z-HAjob39Ip&ILST23FRtMIWBIfFdlTMKhy}a-&lRa@fQo7g$u3l13Nh(i#SxGdm#0 zLqY%>;3>po%d>N&M~ixKNjMh77>amJ_*^Zz*l0p@4i`X_GNnu|jrXuCaddV7660bl zWU78%KLng<(Hx$4k{IT8yJc=d=5Sdtg+`;n4>;Pz zI(gP%M+8jD>?q*1C<^t+i}-9#qj3P<&h@hZ`M^As6I00Kn9YU__Tc#Vl@O#qpr7^N z(%>n@QUT{EaM2)sC9v}mgCQ7tz~5Qm%JZhf&=|-AHfYMhRTV>)OfVQt10DheR@Ub9 zdO@;>Sn{mpC0Rpa6Exm*1_uJ&2XKd2zsTKd46TetQtzM(gzyY{Eh?-}G7g$$NbgXo zu@Dp;t&-wEK}nTNltrqcqEu3anWhu~r=l6Nc@UJr&heC;1_BfWm$48>6Af?`p~j^O z3ouKS(F~AMYC;Xz{hwmgyL;QEDLQQwJL1oHc4ebYSFdz28wdnibX?n{BARszNw zC&cPg(K(de3Sjr>FV`1x_Ge0g0?}$hrDmjN4TzE|qZnG)KLAHc4W(9_8HQF3MdutA z-c7kctQGPIxq{{C;fcAs=%cKgeevMgkk*&V?xh(k#P+66Ha2h z27{Um^y`zs<^_8pHqZ?FITPB>FZk=V4_DVPU9ZHz zD;W=0*Z+;KfS1=PV258pZg^SRS^n*Fc+nbVPEOE!uUw-4=*|?w(P(F47AF#o`IYea zh$<>4LZLrzFvk0T6X+X+Mm`g7Ujc8^27^8}&C}MkCpn}U3DoHh^dvu#afn}0a$>G8iPq#xMocvw4Q#klR=j)p z``QWjlX|Y`tCsm?Y$48kow`25@nzTF#CmkYk?^{0s}9Qk6gwff?W#5;^yI0n#PpDa z`M0au+lfvzTzMZ^&>OR+DKLEYZr|=7wB0qEz>d1NwswZNu3k&=i>R*;-P)G_M^$L% zp6shTwS|>q!;awplFUl%8Cl!vz9E}z|?Fw7@mTevygV*+Km}V zMf&GcxZA;{XD5x1+?jk&|6QABV_9xPM8?O>e=z;ovn@UUwcyK(r)9WGYeH|Ykz9B8 zoL%Tg`oC9y@8-32`^ArTd{y7uz0WUa?x?Af5qBF}4{)0={Elmph}R3en|zk7$^K&b T(-Uh?3sXaUivDQa@^}6Vw^D2p literal 561 zcmV-10?z%3P)Yg5o74iWdZJ^ch4D3lS8O2$CkC7M7;55J5x`Z4@j71>Yi(AVI;# z##&LLNtKKG51fE3nVoZ%xC*iOnuR(0v2!jn>xswXp1*|WU+4#g&cLUJliv_}v=Mr6 zTgVGaHbMo^=%&zsjZB%IY6}Iy5@@wNuLo-kp%|#MtZf6!z%Lb2pZlHyXTc#D1!Ex1 zkSTKmM!+~Y0y%nq3mPOsQOyfJ1Tv;ID_o&2@ao{jQl3EvM`+&#nKHX3p#UffgQ~np zfdu87WNm>eRx7kE2=)fTz-Q@CA&?Qo*|HN-C4Rw_3EH%b08{E5v~a3y-LQ3GMw1H} zwkjrVjB_?Q<71AOoF>MMlTJOY36>I!f}|$Kq!XbjO|XPO=votF!imtlCRmoX!zAOg z*|J%QkQ#`ahT}zuAr!G$uL@>^Bh(JA80DIw($>igQfn~9xug?7RT^W4zLeLpO%bLH zt1wjZvLb7C>`_J{4ogL@UHplYJ5NRr?y$&k*W% z^Iq0u$fvySR#7uoX~ij3kQLQfkN1`F#9k&YN>K zsz!87s*Q9CU|qN9z&WjN>YR+GJ32o!oXxryt*T@8K+j3?v&o+SVG$Xw7u2K9O>EjI zd^-E3g}x9^bA(swgF7Gk`VY-H{o?TUB>o3VKG7R}(pfi4)OF8Xf2xi-$1AnVDL&PC z;{>m;gOYPNtdrx*9QF6?{UFOa@w>(k$Afxb8T7u^?%y3%^b_bG22WQ%mvv4FO#oC~ BWc2_5 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_import_white.png b/app/src/main/res/drawable-mdpi/ic_import_white.png new file mode 100644 index 0000000000000000000000000000000000000000..f90b07ad7594e9ac654b0fd7c63b9f4538cf07e6 GIT binary patch literal 4427 zcmeHKdr%X19$%uK$sl z&F+35pWpZU`F?-j*Sf6%w8bok^$K3 z<5|wdz+$PFfteu3LQwF6+jeo{NmTa3!>I{v-g9l&QmwQ6>)%@LGQVRtRK2bj$DQph zZ9Pj>TB_g4EN;-e@Sf$Gr;5$0`(4w*^chiE56g(?Lz8Eps4Lw4bZ^JZuHP@sSI&Df z!Etnob>8xd4d9`qhv-#WdeGrv0t zy$#cMD<45|zuMp#vn$D}eP1I^{bXO>ug}lzz4XtFCy{rrygL1u=gL1IC}IO=G}b{2c4X~`d^6-(=nMcf3PqSkbj_5 zI+oZ_`(bMF^;yN8TU*iEjwRcha|BuRY)ABD(@T5b-GI4H6@6nlu;tyJ!<#FUuOBa3+w|?4&V-e>Z(hdF^p->Va^IF473z;b-vv3)Uj^2M1jW0RB+WY* zWzg*fjR!$#=|L|^6*D62V4R%CAiv$xDu+4RAYY=fqE@ewDdNm!J|?d$$4-?MQ+isS zJ|`wENB{sgBa(2??eYjj&>#=t65v@9BXT%oA{HCu1y&nuuqnOMR#v>*Vg`lYcf3M%?3Z+9+2;*Yhz*GRMs)j9@WwF`@JR}O7 zoZB1n0%Q-f6ghT~tYNW9nov4J0|D*>xWlaba}OBslZkD?f(&}cO}g<7k3DD;eqRp1P*V=y&^(>l!%D2qoBNe{(HPyk%X0US!F!L=Ch zA!&+HsC8Oa;ZSL51*)NNoYk=y%VI+y7Wp{Pm85HER1y>opmel`!cZ-xz%U(%Mu*Z0 z(xFBH6pJ|+N~6PYT?mS%i21zFO@eZAZqmshUXL@RkO(K{+AIb+rbGuNHWw+fz`-D2 z$a(z1L4}=jGkGE@v8mFbDh;YpYqU6u>s0DNqkP6EfKHS!Rj3m0(@13@Kr(<>QtDFx z5b^-I5Jn$EioDOx^Dcv23JI1x2h>)uooG@dO{B;GP!z)n6-J<#U4;`GHK9_apc(=n zV$ahYTl&AOrOgAU^_ASr31I!wkf?7*Le#A*y$Y98j z0e*clFucGlLTPna)wAcKq072uYNLK_@QyT|_ zQKH3~8Fgbqq%1C0-?3&J5Z$ww=Guc7ZeGluv>u(1(e~oi-X$dn6mj3^!ua#kYW_H* zvFm>IFD=z2D_1AYH_fj4s_^Bph0|`x{?ztdvOoSB6!E0-X2+$T=w;`H{cuJl6cIT_ z7F+*a)S>H3Z29lm(+~W{y!6n{6uG>k`?tQWfBm5PY-f8D{D)&_oEZx$Ce^%YzgnL< zg=_Gw*yRtTXjXplDDv|&jzIEr`E}#OhjYHZGId9LV|U8I#{En6?Q7XZ4-#?~*Ux?$ z?N3eL(SGZrF4v-JF=da;_BZDiBL3v8a0KQ(2hS}|X&p+VI>z9we d4HB8O`k9{Yf}pRU`+&rlB{Rp=IB&(e{{r%cN#g(j literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_settings.png b/app/src/main/res/drawable-mdpi/ic_settings.png index cf6c63e77bd1d3b919ab8e8b1882df7af687feb7..bda5e854555c9d00cfab623cc26b1e8c7d032800 100644 GIT binary patch literal 4511 zcmeHKeNYo;8V`aJ5oqL8RIs-$*H+YIlifg)m8g&)1Pn&xL(2KF*?kjM$OqZQ1pGiN z=VvP-*H#e~to67mj#aFPUvNNm^c=mj);p&37}TqCO0`gjyQ=lx4Tv!9%#AbG|H#Z{ z-}m|Wz0dP|pZA%4x0q5Af&wN7h(w|wL!v$vz7vHefN89 z$=&I@0*lX0%J-|={`UFch_HDbl5Tm8B4hfYp28B4oS758g0FaTepCIm^XCe>iyO~Q zjnMdp1XWFud@|-iWrwlQt_`&|ZrqLCVHeE0_uAv$tOzV@eT_)uQ^M+WCWB7*A|04S z<(e{WV)NYa)@6(0%RUHRDajY7?wz@Lt9r%wt){781k{qde*42nI_+^@cz zbUbNwN{r>NBe(qe^ij{#&rjbw-bj38c~iR}{EZ3QrX1nrGj>n@Ze0HSoBZX_|GzZ;O(!rnA|y5rEZlG5VqkCX4DUP>Po zadE^a*O4=8AIES-*!Fd`Ug?_<604}a=lj?yf6rsori_xwb(eHq#ZUH#W>7B=CL_p z-HAjob39Ip&ILST23FRtMIWBIfFdlTMKhy}a-&lRa@fQo7g$u3l13Nh(i#SxGdm#0 zLqY%>;3>po%d>N&M~ixKNjMh77>amJ_*^Zz*l0p@4i`X_GNnu|jrXuCaddV7660bl zWU78%KLng<(Hx$4k{IT8yJc=d=5Sdtg+`;n4>;Pz zI(gP%M+8jD>?q*1C<^t+i}-9#qj3P<&h@hZ`M^As6I00Kn9YU__Tc#Vl@O#qpr7^N z(%>n@QUT{EaM2)sC9v}mgCQ7tz~5Qm%JZhf&=|-AHfYMhRTV>)OfVQt10DheR@Ub9 zdO@;>Sn{mpC0Rpa6Exm*1_uJ&2XKd2zsTKd46TetQtzM(gzyY{Eh?-}G7g$$NbgXo zu@Dp;t&-wEK}nTNltrqcqEu3anWhu~r=l6Nc@UJr&heC;1_BfWm$48>6Af?`p~j^O z3ouKS(F~AMYC;Xz{hwmgyL;QEDLQQwJL1oHc4ebYSFdz28wdnibX?n{BARszNw zC&cPg(K(de3Sjr>FV`1x_Ge0g0?}$hrDmjN4TzE|qZnG)KLAHc4W(9_8HQF3MdutA z-c7kctQGPIxq{{C;fcAs=%cKgeevMgkk*&V?xh(k#P+66Ha2h z27{Um^y`zs<^_8pHqZ?FITPB>FZk=V4_DVPU9ZHz zD;W=0*Z+;KfS1=PV258pZg^SRS^n*Fc+nbVPEOE!uUw-4=*|?w(P(F47AF#o`IYea zh$<>4LZLrzFvk0T6X+X+Mm`g7Ujc8^27^8}&C}MkCpn}U3DoHh^dvu#afn}0a$>G8iPq#xMocvw4Q#klR=j)p z``QWjlX|Y`tCsm?Y$48kow`25@nzTF#CmkYk?^{0s}9Qk6gwff?W#5;^yI0n#PpDa z`M0au+lfvzTzMZ^&>OR+DKLEYZr|=7wB0qEz>d1NwswZNu3k&=i>R*;-P)G_M^$L% zp6shTwS|>q!;awplFUl%8Cl!vz9E}z|?Fw7@mTevygV*+Km}V zMf&GcxZA;{XD5x1+?jk&|6QABV_9xPM8?O>e=z;ovn@UUwcyK(r)9WGYeH|Ykz9B8 zoL%Tg`oC9y@8-32`^ArTd{y7uz0WUa?x?Af5qBF}4{)0={Elmph}R3en|zk7$^K&b T(-Uh?3sXaUivDQa@^}6Vw^D2p literal 383 zcmV-_0f7FAP)#?3&@f)y}`*ETi`c}Bk$uoYN%hbn5w0<{}j zKnd^0f^9#aR&5atqxKDR)(pn+sGPi@+>oO3OCB&5x~6MlQ8nip)i)+uy dzxvbf*e?paUtkY>%r^i4002ovPDHLkV1nA#pziUx!2;v>Qfw8eS*wk!USa$bLz4e(D#^O)gYEO3${(=WG z)4zTd$aJq~YL;{EP2lI95P}cE?>|F+U$hW-3chLu++L%kw_c6kv}g$ysIIhZP9H3V5&rAy@$qRv-i`;K2%nUuK$sl z&F+35pWpZU`F?-j*Sf6%w8bok^$K3 z<5|wdz+$PFfteu3LQwF6+jeo{NmTa3!>I{v-g9l&QmwQ6>)%@LGQVRtRK2bj$DQph zZ9Pj>TB_g4EN;-e@Sf$Gr;5$0`(4w*^chiE56g(?Lz8Eps4Lw4bZ^JZuHP@sSI&Df z!Etnob>8xd4d9`qhv-#WdeGrv0t zy$#cMD<45|zuMp#vn$D}eP1I^{bXO>ug}lzz4XtFCy{rrygL1u=gL1IC}IO=G}b{2c4X~`d^6-(=nMcf3PqSkbj_5 zI+oZ_`(bMF^;yN8TU*iEjwRcha|BuRY)ABD(@T5b-GI4H6@6nlu;tyJ!<#FUuOBa3+w|?4&V-e>Z(hdF^p->Va^IF473z;b-vv3)Uj^2M1jW0RB+WY* zWzg*fjR!$#=|L|^6*D62V4R%CAiv$xDu+4RAYY=fqE@ewDdNm!J|?d$$4-?MQ+isS zJ|`wENB{sgBa(2??eYjj&>#=t65v@9BXT%oA{HCu1y&nuuqnOMR#v>*Vg`lYcf3M%?3Z+9+2;*Yhz*GRMs)j9@WwF`@JR}O7 zoZB1n0%Q-f6ghT~tYNW9nov4J0|D*>xWlaba}OBslZkD?f(&}cO}g<7k3DD;eqRp1P*V=y&^(>l!%D2qoBNe{(HPyk%X0US!F!L=Ch zA!&+HsC8Oa;ZSL51*)NNoYk=y%VI+y7Wp{Pm85HER1y>opmel`!cZ-xz%U(%Mu*Z0 z(xFBH6pJ|+N~6PYT?mS%i21zFO@eZAZqmshUXL@RkO(K{+AIb+rbGuNHWw+fz`-D2 z$a(z1L4}=jGkGE@v8mFbDh;YpYqU6u>s0DNqkP6EfKHS!Rj3m0(@13@Kr(<>QtDFx z5b^-I5Jn$EioDOx^Dcv23JI1x2h>)uooG@dO{B;GP!z)n6-J<#U4;`GHK9_apc(=n zV$ahYTl&AOrOgAU^_ASr31I!wkf?7*Le#A*y$Y98j z0e*clFucGlLTPna)wAcKq072uYNLK_@QyT|_ zQKH3~8Fgbqq%1C0-?3&J5Z$ww=Guc7ZeGluv>u(1(e~oi-X$dn6mj3^!ua#kYW_H* zvFm>IFD=z2D_1AYH_fj4s_^Bph0|`x{?ztdvOoSB6!E0-X2+$T=w;`H{cuJl6cIT_ z7F+*a)S>H3Z29lm(+~W{y!6n{6uG>k`?tQWfBm5PY-f8D{D)&_oEZx$Ce^%YzgnL< zg=_Gw*yRtTXjXplDDv|&jzIEr`E}#OhjYHZGId9LV|U8I#{En6?Q7XZ4-#?~*Ux?$ z?N3eL(SGZrF4v-JF=da;_BZDiBL3v8a0KQ(2hS}|X&p+VI>z9we d4HB8O`k9{Yf}pRU`+&rlB{Rp=IB&(e{{r%cN#g(j literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_settings.png b/app/src/main/res/drawable-xhdpi/ic_settings.png index 31709168d68785fdb65de7f2c439be8d1ac83e31..bda5e854555c9d00cfab623cc26b1e8c7d032800 100644 GIT binary patch literal 4511 zcmeHKeNYo;8V`aJ5oqL8RIs-$*H+YIlifg)m8g&)1Pn&xL(2KF*?kjM$OqZQ1pGiN z=VvP-*H#e~to67mj#aFPUvNNm^c=mj);p&37}TqCO0`gjyQ=lx4Tv!9%#AbG|H#Z{ z-}m|Wz0dP|pZA%4x0q5Af&wN7h(w|wL!v$vz7vHefN89 z$=&I@0*lX0%J-|={`UFch_HDbl5Tm8B4hfYp28B4oS758g0FaTepCIm^XCe>iyO~Q zjnMdp1XWFud@|-iWrwlQt_`&|ZrqLCVHeE0_uAv$tOzV@eT_)uQ^M+WCWB7*A|04S z<(e{WV)NYa)@6(0%RUHRDajY7?wz@Lt9r%wt){781k{qde*42nI_+^@cz zbUbNwN{r>NBe(qe^ij{#&rjbw-bj38c~iR}{EZ3QrX1nrGj>n@Ze0HSoBZX_|GzZ;O(!rnA|y5rEZlG5VqkCX4DUP>Po zadE^a*O4=8AIES-*!Fd`Ug?_<604}a=lj?yf6rsori_xwb(eHq#ZUH#W>7B=CL_p z-HAjob39Ip&ILST23FRtMIWBIfFdlTMKhy}a-&lRa@fQo7g$u3l13Nh(i#SxGdm#0 zLqY%>;3>po%d>N&M~ixKNjMh77>amJ_*^Zz*l0p@4i`X_GNnu|jrXuCaddV7660bl zWU78%KLng<(Hx$4k{IT8yJc=d=5Sdtg+`;n4>;Pz zI(gP%M+8jD>?q*1C<^t+i}-9#qj3P<&h@hZ`M^As6I00Kn9YU__Tc#Vl@O#qpr7^N z(%>n@QUT{EaM2)sC9v}mgCQ7tz~5Qm%JZhf&=|-AHfYMhRTV>)OfVQt10DheR@Ub9 zdO@;>Sn{mpC0Rpa6Exm*1_uJ&2XKd2zsTKd46TetQtzM(gzyY{Eh?-}G7g$$NbgXo zu@Dp;t&-wEK}nTNltrqcqEu3anWhu~r=l6Nc@UJr&heC;1_BfWm$48>6Af?`p~j^O z3ouKS(F~AMYC;Xz{hwmgyL;QEDLQQwJL1oHc4ebYSFdz28wdnibX?n{BARszNw zC&cPg(K(de3Sjr>FV`1x_Ge0g0?}$hrDmjN4TzE|qZnG)KLAHc4W(9_8HQF3MdutA z-c7kctQGPIxq{{C;fcAs=%cKgeevMgkk*&V?xh(k#P+66Ha2h z27{Um^y`zs<^_8pHqZ?FITPB>FZk=V4_DVPU9ZHz zD;W=0*Z+;KfS1=PV258pZg^SRS^n*Fc+nbVPEOE!uUw-4=*|?w(P(F47AF#o`IYea zh$<>4LZLrzFvk0T6X+X+Mm`g7Ujc8^27^8}&C}MkCpn}U3DoHh^dvu#afn}0a$>G8iPq#xMocvw4Q#klR=j)p z``QWjlX|Y`tCsm?Y$48kow`25@nzTF#CmkYk?^{0s}9Qk6gwff?W#5;^yI0n#PpDa z`M0au+lfvzTzMZ^&>OR+DKLEYZr|=7wB0qEz>d1NwswZNu3k&=i>R*;-P)G_M^$L% zp6shTwS|>q!;awplFUl%8Cl!vz9E}z|?Fw7@mTevygV*+Km}V zMf&GcxZA;{XD5x1+?jk&|6QABV_9xPM8?O>e=z;ovn@UUwcyK(r)9WGYeH|Ykz9B8 zoL%Tg`oC9y@8-32`^ArTd{y7uz0WUa?x?Af5qBF}4{)0={Elmph}R3en|zk7$^K&b T(-Uh?3sXaUivDQa@^}6Vw^D2p literal 677 zcmV;W0$TlvP)bJYb>(^WC;{%W2EPK_nD_+Br3HBc#(_Fu4!F*Gev3H>3(V^bo|H(O6U!?qpw;z+ ziAjo*z+Bh@`wAqVVUH`&4*V!2pykp=6|e)R3MHT6geov5InV>(0h+ObXgF{&MkQm9 zQUv;eFTnx)K$*_EDhC3Bv9+A~sB550;BEPF`WcmGyMV+!(7~-j4M3PNZORxeKm`yZ z#y$kE|4@+ zz-S6N1O!?PV#dr6C<3+#i_I$_ut^=u#1do^B2R^DHKt# zoj&5MfmX#1G%5TSSygCPA%Pu{GOCrXcLkDvmFY%3I)Oh;Oj0kFTV^LN25zzfUH~&d zH6A}7B@&P0F;Tmrn*}a&T%r}p_CkZ0r2mg=@hV`2d581{EaAS89j_NSK)Hecyxa{k zkDqycy}q39A2=pe6zFCMbgC%O$PlPg^)u@kA^BtLL$@Vh37E$(b_9MwrgewN00000 LNkvXXu0mjfe-Ri} diff --git a/app/src/main/res/drawable-xxhdpi/ic_home.png b/app/src/main/res/drawable-xxhdpi/ic_home.png new file mode 100644 index 0000000000000000000000000000000000000000..35d7634bb2283707570d0b6bfd00f3e30a84e22a GIT binary patch literal 627 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY1|&n@Zgyv2V6yUbaSW-5dpl#V7jvLU%VIGn zl~9l6b9;OJ7tDRadMT=7Ut^h_;{mtbCT3wPw`|@VBygoX>iG|5t2q@(n`YnHZOt4% zdGGf*GaDzUuAQcG)y*|9NAl0kE59_-`S;XqJbqqUSEPvJUWc>Yb&rJ|3xm&@JKNpY zSlHmbT;$oL_ohx9c4en#9GUU{dKkxUHn}-MN^j0donJjwU<32KIUg=3m0R0v7jxRs z`{=X!9OwVyvo{|6yjhItt(D{R)al<-G+AzzADVj9?)_;m4g-x-KcjpPrSVtfi#2^L zRu2fB^Z8#2>t^i-$2bE`w-vYkRZ*X@r}T_|SM;~ZJqdZDcdVC*_f|%v)_aTcthIKV ze%9)DOjp7Z?s>A!r;pi`-hA)G%53er)&BA4qdVdgrH2j)A9r~* zr=ZWP#Wnrhrx=UJHcPp<-OgRQBT=|+XK2m7$9F7G7aiR+<@36f<^zj2tCZ_pu2D^N z_?<1lzn**A+Os>C3+d%qF~2^g_WXbFjtk8C=N9ZrimblVtSw`sajDLF9oOla1GRsI z_+%`_XCD*%{z=hhM**MtRBpZJr!23OtlM|m^P&H`ke%C`emH+@j*s8!dFWv7z6j=R zme0>@N<7zeC(w~mOT&Scb;SY(QIQEbj@KVlxV_OkKYMBlx7E|1mruR3`kdwpm0r-q v6cW(D#T9_82e+U@C9CHo70;kaRqRiGg$HghU3L$cm>4`={an^LB{Ts5b3qps literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_import_white.png b/app/src/main/res/drawable-xxhdpi/ic_import_white.png new file mode 100644 index 0000000000000000000000000000000000000000..f90b07ad7594e9ac654b0fd7c63b9f4538cf07e6 GIT binary patch literal 4427 zcmeHKdr%X19$%uK$sl z&F+35pWpZU`F?-j*Sf6%w8bok^$K3 z<5|wdz+$PFfteu3LQwF6+jeo{NmTa3!>I{v-g9l&QmwQ6>)%@LGQVRtRK2bj$DQph zZ9Pj>TB_g4EN;-e@Sf$Gr;5$0`(4w*^chiE56g(?Lz8Eps4Lw4bZ^JZuHP@sSI&Df z!Etnob>8xd4d9`qhv-#WdeGrv0t zy$#cMD<45|zuMp#vn$D}eP1I^{bXO>ug}lzz4XtFCy{rrygL1u=gL1IC}IO=G}b{2c4X~`d^6-(=nMcf3PqSkbj_5 zI+oZ_`(bMF^;yN8TU*iEjwRcha|BuRY)ABD(@T5b-GI4H6@6nlu;tyJ!<#FUuOBa3+w|?4&V-e>Z(hdF^p->Va^IF473z;b-vv3)Uj^2M1jW0RB+WY* zWzg*fjR!$#=|L|^6*D62V4R%CAiv$xDu+4RAYY=fqE@ewDdNm!J|?d$$4-?MQ+isS zJ|`wENB{sgBa(2??eYjj&>#=t65v@9BXT%oA{HCu1y&nuuqnOMR#v>*Vg`lYcf3M%?3Z+9+2;*Yhz*GRMs)j9@WwF`@JR}O7 zoZB1n0%Q-f6ghT~tYNW9nov4J0|D*>xWlaba}OBslZkD?f(&}cO}g<7k3DD;eqRp1P*V=y&^(>l!%D2qoBNe{(HPyk%X0US!F!L=Ch zA!&+HsC8Oa;ZSL51*)NNoYk=y%VI+y7Wp{Pm85HER1y>opmel`!cZ-xz%U(%Mu*Z0 z(xFBH6pJ|+N~6PYT?mS%i21zFO@eZAZqmshUXL@RkO(K{+AIb+rbGuNHWw+fz`-D2 z$a(z1L4}=jGkGE@v8mFbDh;YpYqU6u>s0DNqkP6EfKHS!Rj3m0(@13@Kr(<>QtDFx z5b^-I5Jn$EioDOx^Dcv23JI1x2h>)uooG@dO{B;GP!z)n6-J<#U4;`GHK9_apc(=n zV$ahYTl&AOrOgAU^_ASr31I!wkf?7*Le#A*y$Y98j z0e*clFucGlLTPna)wAcKq072uYNLK_@QyT|_ zQKH3~8Fgbqq%1C0-?3&J5Z$ww=Guc7ZeGluv>u(1(e~oi-X$dn6mj3^!ua#kYW_H* zvFm>IFD=z2D_1AYH_fj4s_^Bph0|`x{?ztdvOoSB6!E0-X2+$T=w;`H{cuJl6cIT_ z7F+*a)S>H3Z29lm(+~W{y!6n{6uG>k`?tQWfBm5PY-f8D{D)&_oEZx$Ce^%YzgnL< zg=_Gw*yRtTXjXplDDv|&jzIEr`E}#OhjYHZGId9LV|U8I#{En6?Q7XZ4-#?~*Ux?$ z?N3eL(SGZrF4v-JF=da;_BZDiBL3v8a0KQ(2hS}|X&p+VI>z9we d4HB8O`k9{Yf}pRU`+&rlB{Rp=IB&(e{{r%cN#g(j literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_settings.png b/app/src/main/res/drawable-xxhdpi/ic_settings.png index 55d0279eabea549f3d2c80b017cf4f4251042874..bda5e854555c9d00cfab623cc26b1e8c7d032800 100644 GIT binary patch literal 4511 zcmeHKeNYo;8V`aJ5oqL8RIs-$*H+YIlifg)m8g&)1Pn&xL(2KF*?kjM$OqZQ1pGiN z=VvP-*H#e~to67mj#aFPUvNNm^c=mj);p&37}TqCO0`gjyQ=lx4Tv!9%#AbG|H#Z{ z-}m|Wz0dP|pZA%4x0q5Af&wN7h(w|wL!v$vz7vHefN89 z$=&I@0*lX0%J-|={`UFch_HDbl5Tm8B4hfYp28B4oS758g0FaTepCIm^XCe>iyO~Q zjnMdp1XWFud@|-iWrwlQt_`&|ZrqLCVHeE0_uAv$tOzV@eT_)uQ^M+WCWB7*A|04S z<(e{WV)NYa)@6(0%RUHRDajY7?wz@Lt9r%wt){781k{qde*42nI_+^@cz zbUbNwN{r>NBe(qe^ij{#&rjbw-bj38c~iR}{EZ3QrX1nrGj>n@Ze0HSoBZX_|GzZ;O(!rnA|y5rEZlG5VqkCX4DUP>Po zadE^a*O4=8AIES-*!Fd`Ug?_<604}a=lj?yf6rsori_xwb(eHq#ZUH#W>7B=CL_p z-HAjob39Ip&ILST23FRtMIWBIfFdlTMKhy}a-&lRa@fQo7g$u3l13Nh(i#SxGdm#0 zLqY%>;3>po%d>N&M~ixKNjMh77>amJ_*^Zz*l0p@4i`X_GNnu|jrXuCaddV7660bl zWU78%KLng<(Hx$4k{IT8yJc=d=5Sdtg+`;n4>;Pz zI(gP%M+8jD>?q*1C<^t+i}-9#qj3P<&h@hZ`M^As6I00Kn9YU__Tc#Vl@O#qpr7^N z(%>n@QUT{EaM2)sC9v}mgCQ7tz~5Qm%JZhf&=|-AHfYMhRTV>)OfVQt10DheR@Ub9 zdO@;>Sn{mpC0Rpa6Exm*1_uJ&2XKd2zsTKd46TetQtzM(gzyY{Eh?-}G7g$$NbgXo zu@Dp;t&-wEK}nTNltrqcqEu3anWhu~r=l6Nc@UJr&heC;1_BfWm$48>6Af?`p~j^O z3ouKS(F~AMYC;Xz{hwmgyL;QEDLQQwJL1oHc4ebYSFdz28wdnibX?n{BARszNw zC&cPg(K(de3Sjr>FV`1x_Ge0g0?}$hrDmjN4TzE|qZnG)KLAHc4W(9_8HQF3MdutA z-c7kctQGPIxq{{C;fcAs=%cKgeevMgkk*&V?xh(k#P+66Ha2h z27{Um^y`zs<^_8pHqZ?FITPB>FZk=V4_DVPU9ZHz zD;W=0*Z+;KfS1=PV258pZg^SRS^n*Fc+nbVPEOE!uUw-4=*|?w(P(F47AF#o`IYea zh$<>4LZLrzFvk0T6X+X+Mm`g7Ujc8^27^8}&C}MkCpn}U3DoHh^dvu#afn}0a$>G8iPq#xMocvw4Q#klR=j)p z``QWjlX|Y`tCsm?Y$48kow`25@nzTF#CmkYk?^{0s}9Qk6gwff?W#5;^yI0n#PpDa z`M0au+lfvzTzMZ^&>OR+DKLEYZr|=7wB0qEz>d1NwswZNu3k&=i>R*;-P)G_M^$L% zp6shTwS|>q!;awplFUl%8Cl!vz9E}z|?Fw7@mTevygV*+Km}V zMf&GcxZA;{XD5x1+?jk&|6QABV_9xPM8?O>e=z;ovn@UUwcyK(r)9WGYeH|Ykz9B8 zoL%Tg`oC9y@8-32`^ArTd{y7uz0WUa?x?Af5qBF}4{)0={Elmph}R3en|zk7$^K&b T(-Uh?3sXaUivDQa@^}6Vw^D2p delta 1010 zcmVE>x&)uDK&dwNd94BHK94o;JvVyE2E657^j|D&*(0?z;D`0LI1UV9N;_MHD zplSs{7sDW^Q9;myFbL{W5cJt}LDLoF#F=cepydRDmY6K4kU-ETlLeI!2r3@xf`$P# zKnHLZSQOwhqk!$eYXU)T!dQgAGtsz4o$%(U)N>DQJ#6UsKz;FsdyA6~RXNRhw zDL|*ef<6KhRRo>U5ab`A0Vu~(qy)ci#Gi4Ge_U43On;z{F|aOdzoz@d5XHQun=y`F zV5*FuRK{fQ7LX>8Vz{E}m|}6|PmsOEmICd>0afD6D4NBO0IG;%ao?`ws?K85fLg*U zM@G)SlIn?Kx#@Rni6)B4f_2zn&zv+zy+;!zcqWww$$?~w)pZI@cZaZ%RVo>S+ih6O z-4B`%w0}xW<>`ciG9*%f7A&~6v|Kj`2G_vQ4s8;QAx~#ddXHdmdF+xFQ z3fX)fhak5GIz~`6M~SW;)h@%4pfzETfMx)jI+QIdXC!ckD3)3*#FYfO%T?YI zw-~AOI8S`uG z9(*|=b&H+U)Up{YB$(&uI%$zNEe>ZjKMr{3Gk7N! zwb_`7U)3O|8n-9p04IPi2}+9;?tYNhYWcgk#CEjD@oszJIfIyIz#5P7#sCGtJ&INO zGJ=wD-&Py`#c~3+OSTfNmwtf)g0w5#02n203Sq7K2rguh6?8ugf>f5#T?m7qg9?K7g+b6f%&hwa=*7%AD-43{KR2<0 gtRRaOWChXi7gbDK11BI4^#A|>07*qoM6N<$f_C`Nk^lez diff --git a/app/src/main/res/layout-land/activity_main.xml b/app/src/main/res/layout-land/activity_main.xml index 08a56bf..c483435 100644 --- a/app/src/main/res/layout-land/activity_main.xml +++ b/app/src/main/res/layout-land/activity_main.xml @@ -95,14 +95,24 @@ + + + + + - \ No newline at end of file diff --git a/app/src/main/res/layout-xlarge/activity_main.xml b/app/src/main/res/layout-xlarge/activity_main.xml index bf2bde7..cd45fdd 100644 --- a/app/src/main/res/layout-xlarge/activity_main.xml +++ b/app/src/main/res/layout-xlarge/activity_main.xml @@ -94,15 +94,25 @@ + + + + - \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 6ed3db9..81e3cdf 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -15,7 +15,7 @@ android:id="@+id/idTable" android:layout_width="0dp" android:layout_height="200dp" - android:visibility="visible" + android:visibility="visible" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> @@ -88,36 +88,46 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> - + - + - + + + + + - \ No newline at end of file diff --git a/app/src/main/res/menu/activity_main_bottom_toolbar.xml b/app/src/main/res/menu/activity_main_bottom_toolbar.xml new file mode 100644 index 0000000..6c2fa92 --- /dev/null +++ b/app/src/main/res/menu/activity_main_bottom_toolbar.xml @@ -0,0 +1,23 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/activity_main_toolbar.xml b/app/src/main/res/menu/activity_main_toolbar.xml index 4d217d2..53a2b3d 100644 --- a/app/src/main/res/menu/activity_main_toolbar.xml +++ b/app/src/main/res/menu/activity_main_toolbar.xml @@ -1,14 +1,16 @@ + xmlns:app="http://schemas.android.com/apk/res-auto" + > + + - \ No newline at end of file diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 60d2fe0..285561f 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -36,4 +36,13 @@ android:key="org.phenoapps.verify.TUTORIAL_MODE" android:summary="Always display the tutorial when Verify is opened." android:title="Tutorial" /> + + \ No newline at end of file From 97bf7edf6d25fe39257e85cc0b1fd1f6c281f517 Mon Sep 17 00:00:00 2001 From: Siddharth Malladi Date: Thu, 14 Dec 2023 10:13:20 -0800 Subject: [PATCH 02/10] About was migrated. App now updated with the latest About info --- app/build.gradle | 5 +- app/src/main/AndroidManifest.xml | 43 ++++++---- .../org/phenoapps/verify/AboutActivity.java | 83 +++++++++++++++++++ .../phenoapps/verify/SettingsFragment.java | 53 +----------- .../main/res/drawable/ic_person_profile.xml | 10 +++ app/src/main/res/values/about_styles.xml | 3 + app/src/main/res/values/styles.xml | 7 ++ 7 files changed, 135 insertions(+), 69 deletions(-) create mode 100644 app/src/main/java/org/phenoapps/verify/AboutActivity.java create mode 100644 app/src/main/res/drawable/ic_person_profile.xml create mode 100644 app/src/main/res/values/about_styles.xml diff --git a/app/build.gradle b/app/build.gradle index 4a5447f..e9899c5 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -11,7 +11,7 @@ android { minSdkVersion 16 targetSdkVersion 34 versionCode 2 - versionName "1.1" + versionName "2" testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' multiDexEnabled = true vectorDrawables.useSupportLibrary = true @@ -58,7 +58,10 @@ dependencies { implementation files('libs/poi-3.12-android-a.jar') implementation files('libs/poi-ooxml-schemas-3.12-20150511-a.jar') implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + implementation 'com.google.android.material:material:1.9.0' + implementation 'com.github.daniel-stoneuk:material-about-library:3.1.2' } repositories { mavenCentral() + maven { url 'https://jitpack.io' } } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b290ec8..444bbcc 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -12,31 +12,38 @@ android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> - + + android:exported="true" + android:windowSoftInputMode="adjustPan"> + - - - - - - - - - + android:name=".CompareActivity" + android:exported="true" /> + + + + - \ No newline at end of file + diff --git a/app/src/main/java/org/phenoapps/verify/AboutActivity.java b/app/src/main/java/org/phenoapps/verify/AboutActivity.java new file mode 100644 index 0000000..6f05bba --- /dev/null +++ b/app/src/main/java/org/phenoapps/verify/AboutActivity.java @@ -0,0 +1,83 @@ +package org.phenoapps.verify; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; +import androidx.swiperefreshlayout.widget.CircularProgressDrawable; + +import android.content.Context; +import android.net.Uri; +import android.os.Bundle; + +import com.danielstone.materialaboutlibrary.ConvenienceBuilder; +import com.danielstone.materialaboutlibrary.MaterialAboutActivity; +import com.danielstone.materialaboutlibrary.items.MaterialAboutActionItem; +import com.danielstone.materialaboutlibrary.items.MaterialAboutTitleItem; +import com.danielstone.materialaboutlibrary.model.MaterialAboutCard; +import com.danielstone.materialaboutlibrary.model.MaterialAboutList; + +public class AboutActivity extends MaterialAboutActivity { + + + private CircularProgressDrawable progress; + private MaterialAboutActionItem updateCheckItem; + + + + + @NonNull + @Override + protected MaterialAboutList getMaterialAboutList(@NonNull Context context) { + + MaterialAboutCard.Builder appCardBuilder = new MaterialAboutCard.Builder(); + + appCardBuilder.addItem(new MaterialAboutTitleItem.Builder().text("CheckList").icon(R.mipmap.ic_launcher).build()); + + appCardBuilder.addItem(ConvenienceBuilder.createVersionActionItem(this, + getResources().getDrawable(R.drawable.ic_about), + "Version", + false)); + + MaterialAboutCard.Builder authorCardBuilder = new MaterialAboutCard.Builder(); + authorCardBuilder.title("Developers"); + + authorCardBuilder.addItem(new MaterialAboutActionItem.Builder() + .text(getString(R.string.dev_chaney)) + .subText("\t\t"+getString(R.string.ksu)) + .icon(R.drawable.ic_person_profile) + .build()); + authorCardBuilder.addItem(new MaterialAboutActionItem.Builder() + .text(getString(R.string.dev_trevor)) + .subText("\t\t"+getString(R.string.ksu)+"\n\t\t"+getString(R.string.dev_trevor_email)) + .icon(R.drawable.ic_person_profile) + .build()); + authorCardBuilder.addItem(new MaterialAboutActionItem.Builder() + .text(getString(R.string.dev_jesse)) + .subText("\t\t"+getString(R.string.ksu)+"\n\t\t"+getString(R.string.dev_jesse_email)+ + "\n\t\t"+"http://wheatgenetics.org") + .icon(R.drawable.ic_person_profile) + .build()); + + MaterialAboutCard.Builder descriptionCard = new MaterialAboutCard.Builder(); + descriptionCard.title("Description"); + descriptionCard.addItem(new MaterialAboutActionItem.Builder() + .text("Verify is an Android application that imports a list of entries, scans barcodes, and " + + "identifies whether it exists in the list of entries along with audio/visual notifications.").build()); + + return new MaterialAboutList(appCardBuilder.build(),authorCardBuilder.build(), descriptionCard.build()); + } + + @Nullable + @Override + protected CharSequence getActivityTitle() { + return "About"; + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + progress = new CircularProgressDrawable(this); + progress.setStyle(CircularProgressDrawable.DEFAULT); + progress.start(); + } +} \ No newline at end of file diff --git a/app/src/main/java/org/phenoapps/verify/SettingsFragment.java b/app/src/main/java/org/phenoapps/verify/SettingsFragment.java index 89c8970..0092384 100644 --- a/app/src/main/java/org/phenoapps/verify/SettingsFragment.java +++ b/app/src/main/java/org/phenoapps/verify/SettingsFragment.java @@ -20,57 +20,10 @@ private void showChangeLog() { } private void showAboutDialog(Context ctx) { - android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(ctx); - { - android.view.View personView = null; - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { - personView = getLayoutInflater().inflate( - R.layout.about, new android.widget.LinearLayout(ctx), - false); - } - { - assert personView != null; - android.widget.TextView versionTextView = (android.widget.TextView) - personView.findViewById(org.phenoapps.verify.R.id.tvVersion); - try - { - android.content.pm.PackageInfo packageInfo = - ctx.getPackageManager().getPackageInfo(ctx.getPackageName(), 0); - assert packageInfo != null; - assert versionTextView != null; - versionTextView.setText(this.getResources().getString( - org.phenoapps.verify.R.string.versiontitle) + - ' ' + packageInfo.versionName); - } - catch (android.content.pm.PackageManager.NameNotFoundException e) - { e.printStackTrace(); } - versionTextView.setOnClickListener(new android.view.View.OnClickListener() - { - @java.lang.Override - public void onClick(android.view.View v) - { showChangeLog(); } - }); - } - - builder.setCancelable(true); - builder.setTitle (this.getResources().getString( - org.phenoapps.verify.R.string.about)); - builder.setView(personView); + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { + Intent i = new Intent(getContext(), AboutActivity.class); + startActivity(i); } - - builder.setNegativeButton( - this.getResources().getString(org.phenoapps.verify.R.string.ok), - new android.content.DialogInterface.OnClickListener() - { - @java.lang.Override - public void onClick(android.content.DialogInterface dialog, int which) - { - assert dialog != null; - dialog.dismiss(); - } - }); - - builder.show(); } @Override diff --git a/app/src/main/res/drawable/ic_person_profile.xml b/app/src/main/res/drawable/ic_person_profile.xml new file mode 100644 index 0000000..d21debf --- /dev/null +++ b/app/src/main/res/drawable/ic_person_profile.xml @@ -0,0 +1,10 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/values/about_styles.xml b/app/src/main/res/values/about_styles.xml new file mode 100644 index 0000000..55344e5 --- /dev/null +++ b/app/src/main/res/values/about_styles.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index dfd0a57..855819f 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -15,4 +15,11 @@ @color/colorAccent + + + + From 156fb4f77b13a0eb9c0643bbb4fa8ec38f555ae0 Mon Sep 17 00:00:00 2001 From: SidMalladi Date: Mon, 12 Feb 2024 15:05:07 -0500 Subject: [PATCH 03/10] bottom-nav-bar added to all screens --- .../org/phenoapps/verify/CompareActivity.kt | 2 ++ .../phenoapps/verify/LoaderDBActivity.java | 24 ++++++++++++++++ .../org/phenoapps/verify/MainActivity.java | 5 ++-- .../phenoapps/verify/SettingsActivity.java | 4 +-- app/src/main/res/menu/nav_drawer_view.xml | 28 ------------------- app/src/main/res/xml/preferences.xml | 11 ++------ 6 files changed, 33 insertions(+), 41 deletions(-) delete mode 100644 app/src/main/res/menu/nav_drawer_view.xml diff --git a/app/src/main/java/org/phenoapps/verify/CompareActivity.kt b/app/src/main/java/org/phenoapps/verify/CompareActivity.kt index 1a066d8..30c1d8d 100644 --- a/app/src/main/java/org/phenoapps/verify/CompareActivity.kt +++ b/app/src/main/java/org/phenoapps/verify/CompareActivity.kt @@ -192,6 +192,8 @@ class CompareActivity : AppCompatActivity() { barcodeScannerView.pause() } + + override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean { return barcodeScannerView.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event) diff --git a/app/src/main/java/org/phenoapps/verify/LoaderDBActivity.java b/app/src/main/java/org/phenoapps/verify/LoaderDBActivity.java index 249f417..6b7b01b 100644 --- a/app/src/main/java/org/phenoapps/verify/LoaderDBActivity.java +++ b/app/src/main/java/org/phenoapps/verify/LoaderDBActivity.java @@ -6,9 +6,13 @@ import android.database.sqlite.SQLiteException; import android.net.Uri; import android.os.Bundle; + +import androidx.appcompat.widget.ActionMenuView; import androidx.core.app.ActivityCompat; import androidx.appcompat.app.AppCompatActivity; import android.util.Log; +import android.view.Menu; +import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.widget.AbsListView; @@ -514,6 +518,26 @@ protected void onSaveInstanceState(Bundle outState) { if (mFileUri != null) outState.putString(VerifyConstants.CSV_URI, mFileUri.toString()); } + @Override + final public boolean onCreateOptionsMenu(Menu m) { + + final MenuInflater inflater = getMenuInflater(); + inflater.inflate(org.phenoapps.verify.R.menu.activity_main_toolbar, m); + + ActionMenuView bottomToolBar = (ActionMenuView) findViewById(R.id.bottom_toolbar); + Menu bottomMenu = bottomToolBar.getMenu(); + inflater.inflate(R.menu.activity_main_bottom_toolbar, bottomMenu); + + for (int i = 0; i < bottomMenu.size(); i++) { + bottomMenu.getItem(i).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + return onOptionsItemSelected(item); + } + }); + } + return true; + } @Override public boolean onOptionsItemSelected(MenuItem item) { diff --git a/app/src/main/java/org/phenoapps/verify/MainActivity.java b/app/src/main/java/org/phenoapps/verify/MainActivity.java index f98a6e9..35088dd 100644 --- a/app/src/main/java/org/phenoapps/verify/MainActivity.java +++ b/app/src/main/java/org/phenoapps/verify/MainActivity.java @@ -445,10 +445,9 @@ private synchronized void exertModeFunction(@NonNull String id) { final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss", Locale.getDefault()); if (sqlUpdateUserAndDate != null) { //no db yet - String firstName = sharedPref.getString(SettingsActivity.FIRST_NAME, ""); - String lastName = sharedPref.getString(SettingsActivity.LAST_NAME, ""); + String name = sharedPref.getString(SettingsActivity.NAME, ""); sqlUpdateUserAndDate.bindAllArgsAsStrings(new String[]{ - firstName + " " + lastName, + name, sdf.format(c.getTime()), id }); diff --git a/app/src/main/java/org/phenoapps/verify/SettingsActivity.java b/app/src/main/java/org/phenoapps/verify/SettingsActivity.java index f12ff6e..d35764d 100644 --- a/app/src/main/java/org/phenoapps/verify/SettingsActivity.java +++ b/app/src/main/java/org/phenoapps/verify/SettingsActivity.java @@ -15,8 +15,8 @@ public class SettingsActivity extends AppCompatActivity { public static String SCAN_MODE_LIST = "org.phenoapps.verify.SCAN_MODE"; public static String AUDIO_ENABLED = "org.phenoapps.verify.AUDIO_ENABLED"; public static String TUTORIAL_MODE = "org.phenoapps.verify.TUTORIAL_MODE"; - public static String FIRST_NAME = "org.phenoapps.verify.FIRST_NAME"; - public static String LAST_NAME = "org.phenoapps.verify.LAST_NAME"; + public static String NAME = "org.phenoapps.verify.NAME"; + public static String LIST_KEY_NAME = "org.phenoapps.verify.LIST_KEY_NAME"; public static String PAIR_NAME = "org.phenoapps.verify.PAIR_NAME"; public static String DISABLE_PAIR = "org.phenoapps.verify.DISABLE_PAIR"; diff --git a/app/src/main/res/menu/nav_drawer_view.xml b/app/src/main/res/menu/nav_drawer_view.xml deleted file mode 100644 index 0ace8bc..0000000 --- a/app/src/main/res/menu/nav_drawer_view.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 285561f..9fb29ae 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -10,14 +10,9 @@ android:title="@string/prefs_mode" /> - + android:key="org.phenoapps.verify.NAME" + android:summary="Name of person scanning items" + android:title="Name" /> Date: Tue, 13 Feb 2024 08:04:04 -0500 Subject: [PATCH 04/10] updated bottom-nav-bar which was previously crashing. Also added a UX element in which user knows which tab hes in since its highlighted --- app/build.gradle | 11 +- .../org/phenoapps/verify/CompareActivity.kt | 3 - .../org/phenoapps/verify/CompareFragment.kt | 204 ++++ .../org/phenoapps/verify/HomeFragment.java | 1026 +++++++++++++++++ .../phenoapps/verify/LoaderDBActivity.java | 26 +- .../org/phenoapps/verify/MainActivity.java | 990 +--------------- .../phenoapps/verify/SettingsActivity.java | 53 - .../phenoapps/verify/SettingsFragment.java | 38 +- .../main/res/drawable/bottom_nav_color.xml | 5 + .../main/res/layout-land/activity_main.xml | 129 +-- .../main/res/layout-xlarge/activity_main.xml | 124 +- app/src/main/res/layout/activity_main.xml | 146 +-- app/src/main/res/layout/fragment_compare.xml | 51 + app/src/main/res/layout/fragment_home.xml | 117 ++ .../res/menu/activity_main_bottom_toolbar.xml | 3 - .../main/res/navigation/mobile_navigation.xml | 25 + app/src/main/res/values-night/themes.xml | 7 + app/src/main/res/values/attrs.xml | 6 + app/src/main/res/values/colors.xml | 6 + app/src/main/res/values/strings.xml | 4 + app/src/main/res/values/styles.xml | 4 + app/src/main/res/values/themes.xml | 7 + app/src/main/res/xml/preferences.xml | 3 +- 23 files changed, 1585 insertions(+), 1403 deletions(-) create mode 100644 app/src/main/java/org/phenoapps/verify/CompareFragment.kt create mode 100644 app/src/main/java/org/phenoapps/verify/HomeFragment.java delete mode 100644 app/src/main/java/org/phenoapps/verify/SettingsActivity.java create mode 100644 app/src/main/res/drawable/bottom_nav_color.xml create mode 100644 app/src/main/res/layout/fragment_compare.xml create mode 100644 app/src/main/res/layout/fragment_home.xml create mode 100644 app/src/main/res/navigation/mobile_navigation.xml create mode 100644 app/src/main/res/values-night/themes.xml create mode 100644 app/src/main/res/values/attrs.xml create mode 100644 app/src/main/res/values/themes.xml diff --git a/app/build.gradle b/app/build.gradle index e9899c5..b62b6e6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -40,6 +40,9 @@ android { targetCompatibility 1.8 sourceCompatibility 1.8 } + buildFeatures { + viewBinding true + } } dependencies { @@ -49,16 +52,20 @@ dependencies { }) implementation 'com.journeyapps:zxing-android-embedded:3.6.0' implementation 'androidx.appcompat:appcompat:1.6.1' - implementation 'com.google.android.material:material:1.10.0' + implementation 'com.google.android.material:material:1.11.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'androidx.vectordrawable:vectordrawable:1.1.0' implementation 'com.github.apl-devs:appintro:v4.2.0' + implementation "androidx.navigation:navigation-fragment-ktx:2.7.7" + implementation 'androidx.preference:preference-ktx:1.1.1' + implementation "androidx.navigation:navigation-ui-ktx:2.7.7" testImplementation 'junit:junit:4.13.2' implementation files('libs/poi-3.12-android-a.jar') + implementation("androidx.navigation:navigation-fragment-ktx:2.7.7") implementation files('libs/poi-ooxml-schemas-3.12-20150511-a.jar') implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - implementation 'com.google.android.material:material:1.9.0' + implementation 'com.google.android.material:material:1.11.0' implementation 'com.github.daniel-stoneuk:material-about-library:3.1.2' } repositories { diff --git a/app/src/main/java/org/phenoapps/verify/CompareActivity.kt b/app/src/main/java/org/phenoapps/verify/CompareActivity.kt index 30c1d8d..845b420 100644 --- a/app/src/main/java/org/phenoapps/verify/CompareActivity.kt +++ b/app/src/main/java/org/phenoapps/verify/CompareActivity.kt @@ -164,7 +164,6 @@ class CompareActivity : AppCompatActivity() { super.onCreate(savedInstanceState) setContentView(org.phenoapps.verify.R.layout.activity_compare) - } @@ -192,8 +191,6 @@ class CompareActivity : AppCompatActivity() { barcodeScannerView.pause() } - - override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean { return barcodeScannerView.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event) diff --git a/app/src/main/java/org/phenoapps/verify/CompareFragment.kt b/app/src/main/java/org/phenoapps/verify/CompareFragment.kt new file mode 100644 index 0000000..868fcb0 --- /dev/null +++ b/app/src/main/java/org/phenoapps/verify/CompareFragment.kt @@ -0,0 +1,204 @@ +package org.phenoapps.verify; + +import android.annotation.SuppressLint; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; +import androidx.fragment.app.Fragment; + +import android.app.Activity; +import android.content.Context +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.text.Editable +import android.text.TextWatcher +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.widget.EditText +import android.widget.ImageView +import android.widget.RadioButton +import android.widget.RadioGroup +import androidx.appcompat.app.AlertDialog +import com.google.zxing.ResultPoint +import com.journeyapps.barcodescanner.BarcodeCallback +import com.journeyapps.barcodescanner.BarcodeResult +import com.journeyapps.barcodescanner.DecoratedBarcodeView + +import org.phenoapps.verify.databinding.FragmentCompareBinding; + +/** + * An example full-screen activity that shows and hides the system UI (i.e. + * status bar and navigation/system bar) with user interaction. + */ + +public class CompareFragment : Fragment() { + + enum class Mode { + Contains, + Matches + } + + private lateinit var view: View; + + private lateinit var barcodeScannerView: DecoratedBarcodeView + private lateinit var firstEditText: EditText + private lateinit var secondEditText: EditText + private lateinit var imageView: ImageView + + private var mMode: Mode = Mode.Matches + + private var mFocused: Int = R.id.editText + + private val callback = object : BarcodeCallback { + + override fun barcodeResult(result: BarcodeResult) { + + barcodeScannerView.pause() + + result.text?.let { + + view.findViewById(mFocused).setText(result.text ?: "") + + mFocused = when (mFocused) { + R.id.editText -> R.id.editText2 + else -> R.id.editText + } + + view.findViewById(mFocused).requestFocus() + } + barcodeScannerView.resume() + } + override fun possibleResultPoints(resultPoints: MutableList?) { + } + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + var layoutView = inflater.inflate(R.layout.activity_compare, container, false); + return layoutView; + } + + + override fun onStart() { + super.onStart() + val choiceView = layoutInflater.inflate(R.layout.choice_compare_layout, null) + + val radioGroup = choiceView.findViewById(R.id.compare_radio_group) + + val containsRadioButton = radioGroup.findViewById(R.id.radioButton) + val matchesRadioButton = radioGroup.findViewById(R.id.radioButton2) + + containsRadioButton.isChecked = true + + val builder = AlertDialog.Builder(context as Context).apply { + + setView(choiceView) + + setTitle("Choose compare mode:") + + setPositiveButton("OK") { _, _ -> + when (radioGroup.checkedRadioButtonId) { + containsRadioButton.id -> mMode = CompareFragment.Mode.Contains + matchesRadioButton.id -> mMode = CompareFragment.Mode.Matches + } + } + } + + builder.show() + + imageView = view.findViewById(R.id.imageView) + firstEditText = view.findViewById(R.id.editText) + secondEditText = view.findViewById(R.id.editText2) + + firstEditText.setOnClickListener { + mFocused = R.id.editText + } + + secondEditText.setOnClickListener { + mFocused = R.id.editText2 + } + + val watcher: TextWatcher = object : TextWatcher { + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { + } + + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + } + + override fun afterTextChanged(s: Editable?) { + + if (firstEditText.text.isNotEmpty() && secondEditText.text.isNotEmpty()) { + + val first = firstEditText.text + val second = secondEditText.text + when (mMode) { + CompareFragment.Mode.Contains -> { + when { + first.contains(second) || second.contains(first) -> { + imageView.setImageResource(R.drawable.ic_checkbox_marked_circle) + } + else -> imageView.setImageResource(R.drawable.ic_alpha_x_circle) + } + } + CompareFragment.Mode.Matches -> { + when { + firstEditText.text.toString() == secondEditText.text.toString() -> { + imageView.setImageResource(R.drawable.ic_checkbox_marked_circle) + } else -> imageView.setImageResource(R.drawable.ic_alpha_x_circle) + } + } + } + imageView.visibility = View.VISIBLE + } + } + + } + + firstEditText.addTextChangedListener(watcher) + secondEditText.addTextChangedListener(watcher) + + barcodeScannerView = view.findViewById(R.id.zxing_barcode_scanner) + barcodeScannerView.barcodeView.cameraSettings.isContinuousFocusEnabled = true + barcodeScannerView.barcodeView.cameraSettings.isBarcodeSceneModeEnabled = true + barcodeScannerView.decodeContinuous(callback) + + val actionBar = (activity as AppCompatActivity).supportActionBar; + if (actionBar != null) { + actionBar.title = "Compare Barcodes" + actionBar.themedContext + } + + imageView.setOnClickListener { + firstEditText.setText("") + secondEditText.setText("") + firstEditText.requestFocus() + imageView.visibility = View.INVISIBLE + } + } + + override fun onResume() { + super.onResume() + + barcodeScannerView.resume() + } + + override fun onPause() { + super.onPause() + + barcodeScannerView.pause() + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + this.view = view; + } +} \ No newline at end of file diff --git a/app/src/main/java/org/phenoapps/verify/HomeFragment.java b/app/src/main/java/org/phenoapps/verify/HomeFragment.java new file mode 100644 index 0000000..f3fb968 --- /dev/null +++ b/app/src/main/java/org/phenoapps/verify/HomeFragment.java @@ -0,0 +1,1026 @@ +package org.phenoapps.verify; + +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.res.Configuration; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteException; +import android.database.sqlite.SQLiteStatement; +import android.media.MediaPlayer; +import android.media.MediaScannerConnection; +import android.net.Uri; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.ActionMenuView; +import androidx.appcompat.widget.Toolbar; +import androidx.core.app.ActivityCompat; +import androidx.core.view.GravityCompat; +import androidx.drawerlayout.widget.DrawerLayout; +import androidx.fragment.app.Fragment; + +import android.os.Environment; +import android.preference.PreferenceManager; +import android.text.InputType; +import android.text.method.ScrollingMovementMethod; +import android.util.Log; +import android.util.SparseArray; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AbsListView; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.EditText; +import android.widget.ListView; +import android.widget.TextView; +import android.widget.Toast; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Calendar; +import java.util.HashSet; +import java.util.Locale; + +public class HomeFragment extends Fragment { + + + final static private String line_separator = System.getProperty("line.separator"); + + private IdEntryDbHelper mDbHelper; + + private SharedPreferences.OnSharedPreferenceChangeListener mPrefListener; + + //database prepared statements + private SQLiteStatement sqlUpdateNote; + private SQLiteStatement sqlDeleteId; + private SQLiteStatement sqlUpdateChecked; + private SQLiteStatement sqlUpdateUserAndDate; + + private SparseArray mIds; + + //global variable to track matching order + private int mMatchingOrder; + + private String mListId; + + //pair mode vars + private String mPairCol; + private String mNextPairVal; + + private String mFileName = ""; + + private Toolbar navigationToolBar; + + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setHasOptionsMenu(true); + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + mIds = new SparseArray<>(); + + SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getContext()); + + final View auxInfo = getView().findViewById(R.id.auxScrollView); + final View auxValue = getView().findViewById(R.id.auxValueView); + + if (sharedPref.getBoolean(SettingsFragment.AUX_INFO, false)) { + auxInfo.setVisibility(View.VISIBLE); + auxValue.setVisibility(View.VISIBLE); + + } else { + auxInfo.setVisibility(View.GONE); + auxValue.setVisibility(View.GONE); + } + + mPrefListener = new SharedPreferences.OnSharedPreferenceChangeListener() { + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) { + + if (sharedPreferences.getBoolean(SettingsFragment.AUX_INFO, false)) { + auxInfo.setVisibility(View.VISIBLE); + auxValue.setVisibility(View.VISIBLE); + } else { + auxInfo.setVisibility(View.GONE); + auxValue.setVisibility(View.GONE); + } + } + }; + + sharedPref.registerOnSharedPreferenceChangeListener(mPrefListener); + + if (!sharedPref.getBoolean("onlyLoadTutorialOnce", false)) { + launchIntro(); + SharedPreferences.Editor editor = sharedPref.edit(); + editor.putBoolean("onlyLoadTutorialOnce", true); + editor.apply(); + } else { + boolean tutorialMode = sharedPref.getBoolean(SettingsFragment.TUTORIAL_MODE, false); + + if (tutorialMode) + launchIntro(); + } + + mFileName = sharedPref.getString(SettingsFragment.FILE_NAME, ""); + + ActivityCompat.requestPermissions(getActivity(), VerifyConstants.permissions, VerifyConstants.PERM_REQ); + + mNextPairVal = null; + mMatchingOrder = 0; + mPairCol = null; + + initializeUIVariables(); + + mDbHelper = new IdEntryDbHelper(getContext()); + + loadSQLToLocal(); + + if (mListId != null) + updateCheckedItems(); + + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + + return inflater.inflate(R.layout.fragment_home, container, false); + } + + + + + private void prepareStatements() { + + final SQLiteDatabase db = mDbHelper.getWritableDatabase(); + try { + String updateNoteQuery = "UPDATE VERIFY SET note = ? WHERE " + mListId + " = ?"; + sqlUpdateNote = db.compileStatement(updateNoteQuery); + + String deleteIdQuery = "DELETE FROM VERIFY WHERE " + mListId + " = ?"; + sqlDeleteId = db.compileStatement(deleteIdQuery); + + String updateCheckedQuery = "UPDATE VERIFY SET color = 1 WHERE " + mListId + " = ?"; + sqlUpdateChecked = db.compileStatement(updateCheckedQuery); + + String updateUserAndDateQuery = + "UPDATE VERIFY SET user = ?, date = ?, scan_count = scan_count + 1 WHERE " + mListId + " = ?"; + sqlUpdateUserAndDate = db.compileStatement(updateUserAndDateQuery); + } catch(SQLiteException e) { + e.printStackTrace(); + } + } + + @Nullable + private ActionBar getSupportActionBar() { + ActionBar actionBar = null; + if (getActivity() instanceof AppCompatActivity) { + AppCompatActivity activity = (AppCompatActivity) getActivity(); + actionBar = activity.getSupportActionBar(); + } + return actionBar; + } + + private void initializeUIVariables() { + + if (getSupportActionBar() != null){ + getSupportActionBar().setTitle("CheckList"); + getSupportActionBar().getThemedContext(); + getSupportActionBar().setHomeButtonEnabled(true); + } + + final EditText scannerTextView = ((EditText) getView().findViewById(R.id.scannerTextView)); + scannerTextView.setSelectAllOnFocus(true); + scannerTextView.setOnKeyListener(new View.OnKeyListener() { + @Override + public boolean onKey(View v, int keyCode, KeyEvent event) { + + if (event.getAction() == KeyEvent.ACTION_DOWN) { + if (keyCode == KeyEvent.KEYCODE_ENTER) { + checkScannedItem(); + } + } + return false; + } + }); + + ListView idTable = ((ListView) getView().findViewById(R.id.idTable)); + idTable.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE); + idTable.setOnItemClickListener(new AdapterView.OnItemClickListener() { + + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + scannerTextView.setText(((TextView) view).getText().toString()); + scannerTextView.setSelection(scannerTextView.getText().length()); + scannerTextView.requestFocus(); + scannerTextView.selectAll(); + checkScannedItem(); + } + }); + + idTable.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { + @Override + public boolean onItemLongClick(AdapterView parent, View view, int position, long id) { +//get app settings + insertNoteIntoDb(((TextView) view).getText().toString()); + return true; + } + }); + + TextView valueView = (TextView) getView().findViewById(R.id.valueView); + valueView.setMovementMethod(new ScrollingMovementMethod()); + + getView().findViewById(org.phenoapps.verify.R.id.clearButton).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + scannerTextView.setText(""); + } + }); + } + + private synchronized void checkScannedItem() { + + SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getContext()); + int scanMode = Integer.valueOf(sharedPref.getString(SettingsFragment.SCAN_MODE_LIST, "-1")); + boolean displayAux = sharedPref.getBoolean(SettingsFragment.AUX_INFO, true); + + String scannedId = ((EditText) getView().findViewById(org.phenoapps.verify.R.id.scannerTextView)) + .getText().toString(); + + if (mIds != null && mIds.size() > 0) { + //update database + exertModeFunction(scannedId); + + //view updated database + SQLiteDatabase db = mDbHelper.getReadableDatabase(); + + String table = IdEntryContract.IdEntry.TABLE_NAME; + String[] selectionArgs = new String[]{scannedId}; + Cursor cursor = db.query(table, null, mListId + "=?", selectionArgs, null, null, null); + + String[] headerTokens = cursor.getColumnNames(); + StringBuilder values = new StringBuilder(); + StringBuilder auxValues = new StringBuilder(); + if (cursor.moveToFirst()) { + for (String header : headerTokens) { + + if (!header.equals(mListId)) { + + final String val = cursor.getString( + cursor.getColumnIndexOrThrow(header) + ); + + if (header.equals("color") || header.equals("scan_count") || header.equals("date") + || header.equals("user") || header.equals("note")) { + if (header.equals("color")) continue; + else if (header.equals("scan_count")) auxValues.append("Number of scans"); + else if (header.equals("date")) auxValues.append("Date"); + else auxValues.append(header); + auxValues.append(" : "); + if (val != null) auxValues.append(val); + auxValues.append(line_separator); + } else { + values.append(header); + values.append(" : "); + if (val != null) values.append(val); + values.append(line_separator); + } + } + } + cursor.close(); + ((TextView) getView().findViewById(org.phenoapps.verify.R.id.valueView)).setText(values.toString()); + ((TextView) getView().findViewById(R.id.auxValueView)).setText(auxValues.toString()); + ((EditText) getView().findViewById(R.id.scannerTextView)).setText(""); + } else { + if (scanMode != 2) { + ringNotification(false); + } + } + } + } + + private Boolean checkIdExists(String id) { + SQLiteDatabase db = mDbHelper.getReadableDatabase(); + + final String table = IdEntryContract.IdEntry.TABLE_NAME; + final String[] selectionArgs = new String[] { id }; + final Cursor cursor = db.query(table, null, mListId + "=?", selectionArgs, null, null, null); + + if (cursor.moveToFirst()) { + cursor.close(); + return true; + } else { + cursor.close(); + return false; + } + } + + private synchronized void insertNoteIntoDb(@NonNull final String id) { + + AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); + builder.setTitle("Enter a note for the given item."); + final EditText input = new EditText(getContext()); + input.setInputType(InputType.TYPE_CLASS_TEXT); + builder.setView(input); + + builder.setPositiveButton("Save", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + String value = input.getText().toString(); + if (!value.isEmpty()) { + + final SQLiteDatabase db = mDbHelper.getWritableDatabase(); + + if (sqlUpdateNote != null) { + sqlUpdateNote.bindAllArgsAsStrings(new String[]{ + value, id + }); + sqlUpdateNote.executeUpdateDelete(); + } + } + } + }); + + builder.show(); + } + + private synchronized void exertModeFunction(@NonNull String id) { + + //get app settings + SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getContext()); + int scanMode = Integer.valueOf(sharedPref.getString(SettingsFragment.SCAN_MODE_LIST, "-1")); + + SQLiteDatabase db = mDbHelper.getWritableDatabase(); + + if (scanMode == 0 ) { //default mode + mMatchingOrder = 0; + ringNotification(checkIdExists(id)); + + } else if (scanMode == 1) { //order mode + final int tableIndex = getTableIndexById(id); + + if (tableIndex != -1) { + if (mMatchingOrder == tableIndex) { + mMatchingOrder++; + Toast.makeText(getContext(), "Order matches id: " + id + " at index: " + tableIndex, Toast.LENGTH_SHORT).show(); + ringNotification(true); + } else { + Toast.makeText(getContext(), "Scanning out of order!", Toast.LENGTH_SHORT).show(); + ringNotification(false); + } + } + } else if (scanMode == 2) { //filter mode, delete rows with given id + + mMatchingOrder = 0; + if (sqlDeleteId != null) { + sqlDeleteId.bindAllArgsAsStrings(new String[]{id}); + sqlDeleteId.executeUpdateDelete(); + } + updateFilteredArrayAdapter(id); + + } else if (scanMode == 3) { //if color mode, update the db to highlight the item + + mMatchingOrder = 0; + if (sqlUpdateChecked != null) { + sqlUpdateChecked.bindAllArgsAsStrings(new String[]{id}); + sqlUpdateChecked.executeUpdateDelete(); + } + } else if (scanMode == 4) { //pair mode + + mMatchingOrder = 0; + + if (mPairCol != null) { + + //if next pair id is waiting, check if it matches scanned id and reset mode + if (mNextPairVal != null) { + if (mNextPairVal.equals(id)) { + ringNotification(true); + Toast.makeText(getContext(), "Scanned paired item: " + id, Toast.LENGTH_SHORT).show(); + } + mNextPairVal = null; + } else { //otherwise query for the current id's pair + String table = IdEntryContract.IdEntry.TABLE_NAME; + String[] columnsNames = new String[] { mPairCol }; + String selection = mListId + "=?"; + String[] selectionArgs = { id }; + Cursor cursor = db.query(table, columnsNames, selection, selectionArgs, null, null, null); + if (cursor.moveToFirst()) { + mNextPairVal = cursor.getString( + cursor.getColumnIndexOrThrow(mPairCol) + ); + } else mNextPairVal = null; + cursor.close(); + } + } + } + //always update user and datetime + final Calendar c = Calendar.getInstance(); + final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss", Locale.getDefault()); + + if (sqlUpdateUserAndDate != null) { //no db yet + String name = sharedPref.getString(SettingsFragment.NAME, ""); + sqlUpdateUserAndDate.bindAllArgsAsStrings(new String[]{ + name, + sdf.format(c.getTime()), + id + }); + sqlUpdateUserAndDate.executeUpdateDelete(); + } + + updateCheckedItems(); + } + + private synchronized void updateCheckedItems() { + + final SQLiteDatabase db = mDbHelper.getReadableDatabase(); + + //list of ideas to populate and update the view with + final HashSet ids = new HashSet<>(); + + final String table = IdEntryContract.IdEntry.TABLE_NAME; + final String[] columns = new String[] { mListId }; + final String selection = "color = 1"; + + try { + final Cursor cursor = db.query(table, columns, selection, null, null, null, null); + if (cursor.moveToFirst()) { + do { + String id = cursor.getString( + cursor.getColumnIndexOrThrow(mListId) + ); + + ids.add(id); + } while (cursor.moveToNext()); + } + cursor.close(); + } catch (SQLiteException e) { + e.printStackTrace(); + } + ListView idTable = (ListView) getView().findViewById(org.phenoapps.verify.R.id.idTable); + for (int position = 0; position < idTable.getCount(); position++) { + + final String id = (idTable.getItemAtPosition(position)).toString(); + + if (ids.contains(id)) { + idTable.setItemChecked(position, true); + } else idTable.setItemChecked(position, false); + } + } + + private synchronized void loadSQLToLocal() { + + mIds = new SparseArray<>(); + + mDbHelper = new IdEntryDbHelper(getContext()); + + final SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getContext()); + mListId = sharedPref.getString(SettingsFragment.LIST_KEY_NAME, null); + mPairCol = sharedPref.getString(SettingsFragment.PAIR_NAME, null); + + if (mListId != null) { + prepareStatements(); + loadBarcodes(); + buildListView(); + } + } + + private void loadBarcodes() { + + SQLiteDatabase db = mDbHelper.getReadableDatabase(); + try { + final String table = IdEntryContract.IdEntry.TABLE_NAME; + final Cursor cursor = db.query(table, null, null, null, null, null, null); + + if (cursor.moveToFirst()) { + do { + final String[] headers = cursor.getColumnNames(); + for (String header : headers) { + + final String val = cursor.getString( + cursor.getColumnIndexOrThrow(header) + ); + + if (header.equals(mListId)) { + mIds.append(mIds.size(), val); + } + } + } while (cursor.moveToNext()); + } + cursor.close(); + + } catch (SQLiteException e) { + e.printStackTrace(); + } + } + + private synchronized void askUserExportFileName() { + + AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); + builder.setTitle("Choose name for exported file."); + final EditText input = new EditText(getContext()); + + final Calendar c = Calendar.getInstance(); + final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()); + + int lastDot = mFileName.lastIndexOf('.'); + if (lastDot != -1) { + mFileName = mFileName.substring(0, lastDot); + } + input.setText("Verify_"+ sdf.format(c.getTime())); + input.setInputType(InputType.TYPE_CLASS_TEXT); + builder.setView(input); + + builder.setPositiveButton("Export", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int which) { + String value = input.getText().toString(); + mFileName = value; + final Intent i; + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) { + i = new Intent(Intent.ACTION_CREATE_DOCUMENT); + i.setType("*/*"); + i.putExtra(Intent.EXTRA_TITLE, value+".csv"); + startActivityForResult(Intent.createChooser(i, "Choose folder to export file."), VerifyConstants.PICK_CUSTOM_DEST); + }else{ + writeToExportPath(); + } + } + }); + builder.show(); + } + + public void writeToExportPath(){ + String value = mFileName; + + if (!value.isEmpty()) { + if (isExternalStorageWritable()) { + try { + File verifyDirectory = new File(Environment.getExternalStorageDirectory().getPath() + "/Verify"); + final File output = new File(verifyDirectory, value + ".csv"); + final FileOutputStream fstream = new FileOutputStream(output); + final SQLiteDatabase db = mDbHelper.getReadableDatabase(); + final String table = IdEntryContract.IdEntry.TABLE_NAME; + final Cursor cursor = db.query(table, null, null, null, null, null, null); + //final Cursor cursor = db.rawQuery("SElECT * FROM VERIFY", null); + + //first write header line + final String[] headers = cursor.getColumnNames(); + for (int i = 0; i < headers.length; i++) { + if (i != 0) fstream.write(",".getBytes()); + fstream.write(headers[i].getBytes()); + } + fstream.write(line_separator.getBytes()); + //populate text file with current database values + if (cursor.moveToFirst()) { + do { + for (int i = 0; i < headers.length; i++) { + if (i != 0) fstream.write(",".getBytes()); + final String val = cursor.getString( + cursor.getColumnIndexOrThrow(headers[i]) + ); + if (val == null) fstream.write("null".getBytes()); + else fstream.write(val.getBytes()); + } + fstream.write(line_separator.getBytes()); + } while (cursor.moveToNext()); + } + + cursor.close(); + fstream.flush(); + fstream.close(); + scanFile(getContext(), output); + /*MediaScannerConnection.scanFile(getContext(), new String[] {output.toString()}, null, new MediaScannerConnection.OnScanCompletedListener() { + @Override + public void onScanCompleted(String path, Uri uri) { + Log.v("scan complete", path); + } + });*/ + }catch (NullPointerException npe){ + npe.printStackTrace(); + Toast.makeText(getContext(), "Error in opening the Specified file", Toast.LENGTH_LONG).show(); + } + catch (SQLiteException e) { + e.printStackTrace(); + Toast.makeText(getContext(), "Error exporting file, is your table empty?", Toast.LENGTH_SHORT).show(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException io) { + io.printStackTrace(); + } + } else { + Toast.makeText(getContext(), + "External storage not writable.", Toast.LENGTH_SHORT).show(); + } + } else { + Toast.makeText(getContext(), + "Must enter a file name.", Toast.LENGTH_SHORT).show(); + } + } + + public static void scanFile(Context ctx, File filePath) { + MediaScannerConnection.scanFile(ctx, new String[] { filePath.getAbsolutePath()}, null, null); + } + + public void writeToExportPath(Uri uri){ + + String value = mFileName; + + if (uri == null){ + Toast.makeText(getContext(), "Unable to open the Specified file", Toast.LENGTH_LONG).show(); + return; + } + + if (!value.isEmpty()) { + if (isExternalStorageWritable()) { + try { + final File output = new File(uri.getPath()); + final OutputStream fstream = getContext().getContentResolver().openOutputStream(uri); + final SQLiteDatabase db = mDbHelper.getReadableDatabase(); + final String table = IdEntryContract.IdEntry.TABLE_NAME; + final Cursor cursor = db.query(table, null, null, null, null, null, null); + //final Cursor cursor = db.rawQuery("SElECT * FROM VERIFY", null); + + //first write header line + final String[] headers = cursor.getColumnNames(); + for (int i = 0; i < headers.length; i++) { + if (i != 0) fstream.write(",".getBytes()); + fstream.write(headers[i].getBytes()); + } + fstream.write(line_separator.getBytes()); + //populate text file with current database values + if (cursor.moveToFirst()) { + do { + for (int i = 0; i < headers.length; i++) { + if (i != 0) fstream.write(",".getBytes()); + final String val = cursor.getString( + cursor.getColumnIndexOrThrow(headers[i]) + ); + if (val == null) fstream.write("null".getBytes()); + else fstream.write(val.getBytes()); + } + fstream.write(line_separator.getBytes()); + } while (cursor.moveToNext()); + } + + cursor.close(); + fstream.flush(); + fstream.close(); + scanFile(getContext(), output); + /*MediaScannerConnection.scanFile(getContext(), new String[] {output.toString()}, null, new MediaScannerConnection.OnScanCompletedListener() { + @Override + public void onScanCompleted(String path, Uri uri) { + Log.v("scan complete", path); + } + });*/ + }catch (NullPointerException npe){ + npe.printStackTrace(); + Toast.makeText(getContext(), "Error in opening the Specified file", Toast.LENGTH_LONG).show(); + } + catch (SQLiteException e) { + e.printStackTrace(); + Toast.makeText(getContext(), "Error exporting file, is your table empty?", Toast.LENGTH_SHORT).show(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException io) { + io.printStackTrace(); + } + } else { + Toast.makeText(getContext(), + "External storage not writable.", Toast.LENGTH_SHORT).show(); + } + } else { + Toast.makeText(getContext(), + "Must enter a file name.", Toast.LENGTH_SHORT).show(); + } + } + + //returns index of table with identifier = id, returns -1 if not found + private int getTableIndexById(String id) { + + ListView idTable = (ListView) getView().findViewById(org.phenoapps.verify.R.id.idTable); + final int size = idTable.getAdapter().getCount(); + int ret = -1; + for (int i = 0; i < size; i++) { + final String temp = (String) idTable.getAdapter().getItem(i); + if (temp.equals(id)) { + ret = i; + break; //break out of for-loop early + } + } + + return ret; + } + + private void updateFilteredArrayAdapter(String id) { + + ListView idTable = (ListView) getView().findViewById(org.phenoapps.verify.R.id.idTable); + //update id table array adapter + final ArrayAdapter updatedAdapter = new ArrayAdapter<>(getContext(), org.phenoapps.verify.R.layout.row); + final int oldSize = idTable.getAdapter().getCount(); + + for (int i = 0; i < oldSize; i++) { + final String temp = (String) idTable.getAdapter().getItem(i); + if (!temp.equals(id)) updatedAdapter.add(temp); + } + idTable.setAdapter(updatedAdapter); + } + + private void ringNotification(boolean success) { + + final SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getContext()); + final boolean audioEnabled = sharedPref.getBoolean(SettingsFragment.AUDIO_ENABLED, true); + + if(success) { //ID found + if(audioEnabled) { + if (success) { + try { + int resID = getResources().getIdentifier("plonk", "raw", getActivity().getPackageName()); + MediaPlayer chimePlayer = MediaPlayer.create(getContext(), resID); + chimePlayer.start(); + + chimePlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { + public void onCompletion(MediaPlayer mp) { + mp.release(); + } + }); + } catch (Exception ignore) { + } + } + } + } + + if(!success) { //ID not found + ((TextView) getView().findViewById(org.phenoapps.verify.R.id.valueView)).setText(""); + + if (audioEnabled) { + if(!success) { + try { + int resID = getResources().getIdentifier("error", "raw", getActivity().getPackageName()); + MediaPlayer chimePlayer = MediaPlayer.create(getContext(), resID); + chimePlayer.start(); + + chimePlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { + public void onCompletion(MediaPlayer mp) { + mp.release(); + } + }); + } catch (Exception ignore) { + } + } + } else { + if (!success) { + Toast.makeText(getContext(), "Scanned ID not found", Toast.LENGTH_SHORT).show(); + } + } + } + } + + @Override + public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { + super.onCreateOptionsMenu(menu, inflater); + inflater.inflate(org.phenoapps.verify.R.menu.activity_main_toolbar, menu); + } + + @Override + final public boolean onOptionsItemSelected(MenuItem item) { + int actionCamera = R.id.action_camera; + int actionImport = R.id.action_import; + + if (item.getItemId() == actionImport){ + final SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getContext()); + final int scanMode = Integer.valueOf(sharedPref.getString(SettingsFragment.SCAN_MODE_LIST, "-1")); + final Intent i; + File verifyDirectory = new File(getContext().getExternalFilesDir(null), "/Verify"); + + File[] files = verifyDirectory.listFiles(); + + + AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); + builder.setTitle("Select files from?"); + builder.setPositiveButton("Storage", + new DialogInterface.OnClickListener() + { + public void onClick(DialogInterface dialog, int id) + { + Intent i; + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) { + i = new Intent(Intent.ACTION_OPEN_DOCUMENT); + }else{ + i = new Intent(Intent.ACTION_GET_CONTENT); + } + i.setType("*/*"); + startActivityForResult(Intent.createChooser(i, "Choose file to import."), VerifyConstants.DEFAULT_CONTENT_REQ); + } + }); + + builder.setNegativeButton("Verify Directory", + new DialogInterface.OnClickListener() + { + public void onClick(DialogInterface dialog, int id) + { + + AlertDialog.Builder fileBuilder = new AlertDialog.Builder(getContext()); + fileBuilder.setTitle("Select the sample file"); + final int[] checkedItem = {-1}; + String[] listItems = verifyDirectory.list(); + Log.d("listItems", "onClick: "+listItems); + fileBuilder.setSingleChoiceItems(listItems, checkedItem[0],(fileDialog, which) -> { + checkedItem[0] = which; + + Intent i = new Intent(getContext(), LoaderDBActivity.class); + i.setData(Uri.fromFile(files[which])); + startActivityForResult(i, VerifyConstants.LOADER_INTENT_REQ); + fileDialog.dismiss(); + }); + + fileBuilder.show(); + + } + }); + builder.show(); + } else if(item.getItemId() == actionCamera){ + final Intent cameraIntent = new Intent(getContext(), ScanActivity.class); + startActivityForResult(cameraIntent, VerifyConstants.CAMERA_INTENT_REQ); + } + else{ + return super.onOptionsItemSelected(item); + } + return true; + } + + @Override + final public void onActivityResult(int requestCode, int resultCode, Intent intent) { + + super.onActivityResult(requestCode, resultCode, intent); + + if (resultCode == getActivity().RESULT_OK) { + + if (intent != null) { + switch (requestCode) { + case VerifyConstants.PICK_CUSTOM_DEST: + writeToExportPath(intent.getData()); + break; + case VerifyConstants.DEFAULT_CONTENT_REQ: + Intent i = new Intent(getContext(), LoaderDBActivity.class); + i.setData(intent.getData()); + startActivityForResult(i, VerifyConstants.LOADER_INTENT_REQ); + break; + case VerifyConstants.LOADER_INTENT_REQ: + + mListId = null; + mPairCol = null; + mFileName = ""; + + if (intent.hasExtra(VerifyConstants.FILE_NAME)) + mFileName = intent.getStringExtra(VerifyConstants.FILE_NAME); + if (intent.hasExtra(VerifyConstants.LIST_ID_EXTRA)) + mListId = intent.getStringExtra(VerifyConstants.LIST_ID_EXTRA); + if (intent.hasExtra(VerifyConstants.PAIR_COL_EXTRA)) + mPairCol = intent.getStringExtra(VerifyConstants.PAIR_COL_EXTRA); + + SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getContext()); + final SharedPreferences.Editor editor = sharedPref.edit(); + + int scanMode = Integer.valueOf(sharedPref.getString(SettingsFragment.SCAN_MODE_LIST, "-1")); + + if (mPairCol != null) { + editor.putBoolean(SettingsFragment.DISABLE_PAIR, false); + if (scanMode != 4) showPairDialog(); + } else { + editor.putBoolean(SettingsFragment.DISABLE_PAIR, true); + } + + if (mPairCol == null && scanMode == 4) { + editor.putString(SettingsFragment.SCAN_MODE_LIST, "0"); + Toast.makeText(getContext(), + "Switching to default mode, no pair ID found.", + Toast.LENGTH_SHORT).show(); + } + editor.putString(SettingsFragment.FILE_NAME, mFileName); + editor.putString(SettingsFragment.PAIR_NAME, mPairCol); + editor.putString(SettingsFragment.LIST_KEY_NAME, mListId); + editor.apply(); + + clearListView(); + loadSQLToLocal(); + updateCheckedItems(); + break; + } + + if (intent.hasExtra(VerifyConstants.CAMERA_RETURN_ID)) { + ((EditText) getView().findViewById(org.phenoapps.verify.R.id.scannerTextView)) + .setText(intent.getStringExtra(VerifyConstants.CAMERA_RETURN_ID)); + checkScannedItem(); + } + } + } + } + + private void buildListView() { + + ListView idTable = (ListView) getView().findViewById(org.phenoapps.verify.R.id.idTable); + ArrayAdapter idAdapter = + new ArrayAdapter<>(getContext(), org.phenoapps.verify.R.layout.row); + int size = mIds.size(); + for (int i = 0; i < size; i++) { + idAdapter.add(this.mIds.get(this.mIds.keyAt(i))); + } + idTable.setAdapter(idAdapter); + } + + private void clearListView() { + + ListView idTable = (ListView) getView().findViewById(org.phenoapps.verify.R.id.idTable); + final ArrayAdapter adapter = + new ArrayAdapter<>(getContext(), org.phenoapps.verify.R.layout.row); + + idTable.setAdapter(adapter); + adapter.notifyDataSetChanged(); + } + + private void showPairDialog() { + + AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); + builder.setTitle("Pair column selected, would you like to switch to Pair mode?"); + + builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + + SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getContext()); + SharedPreferences.Editor editor = sharedPref.edit(); + editor.putString(SettingsFragment.SCAN_MODE_LIST, "4"); + editor.apply(); + } + }); + + builder.setNegativeButton("No thanks", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + + } + }); + + builder.show(); + } + + @Override + final public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + } + + private void launchIntro() { + + new Thread(new Runnable() { + @Override + public void run() { + + // Launch app intro + final Intent i = new Intent(getContext(), IntroActivity.class); + + getActivity().runOnUiThread(new Runnable() { + @Override public void run() { + startActivity(i); + } + }); + + + } + }).start(); + } + + /* Checks if external storage is available for read and write */ + static private boolean isExternalStorageWritable() { + return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()); + } + + @Override + final public void onDestroy() { + mDbHelper.close(); + super.onDestroy(); + } + +} \ No newline at end of file diff --git a/app/src/main/java/org/phenoapps/verify/LoaderDBActivity.java b/app/src/main/java/org/phenoapps/verify/LoaderDBActivity.java index 6b7b01b..eada8d9 100644 --- a/app/src/main/java/org/phenoapps/verify/LoaderDBActivity.java +++ b/app/src/main/java/org/phenoapps/verify/LoaderDBActivity.java @@ -6,13 +6,9 @@ import android.database.sqlite.SQLiteException; import android.net.Uri; import android.os.Bundle; - -import androidx.appcompat.widget.ActionMenuView; import androidx.core.app.ActivityCompat; import androidx.appcompat.app.AppCompatActivity; import android.util.Log; -import android.view.Menu; -import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.widget.AbsListView; @@ -75,7 +71,7 @@ protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_load_file); if(getSupportActionBar() != null){ - getSupportActionBar().setTitle(null); + getSupportActionBar().setTitle("Import Data"); getSupportActionBar().getThemedContext(); getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setHomeButtonEnabled(true); @@ -518,26 +514,6 @@ protected void onSaveInstanceState(Bundle outState) { if (mFileUri != null) outState.putString(VerifyConstants.CSV_URI, mFileUri.toString()); } - @Override - final public boolean onCreateOptionsMenu(Menu m) { - - final MenuInflater inflater = getMenuInflater(); - inflater.inflate(org.phenoapps.verify.R.menu.activity_main_toolbar, m); - - ActionMenuView bottomToolBar = (ActionMenuView) findViewById(R.id.bottom_toolbar); - Menu bottomMenu = bottomToolBar.getMenu(); - inflater.inflate(R.menu.activity_main_bottom_toolbar, bottomMenu); - - for (int i = 0; i < bottomMenu.size(); i++) { - bottomMenu.getItem(i).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem item) { - return onOptionsItemSelected(item); - } - }); - } - return true; - } @Override public boolean onOptionsItemSelected(MenuItem item) { diff --git a/app/src/main/java/org/phenoapps/verify/MainActivity.java b/app/src/main/java/org/phenoapps/verify/MainActivity.java index 35088dd..22d9e32 100644 --- a/app/src/main/java/org/phenoapps/verify/MainActivity.java +++ b/app/src/main/java/org/phenoapps/verify/MainActivity.java @@ -18,8 +18,12 @@ import android.preference.PreferenceManager; import androidx.annotation.NonNull; + +import com.google.android.material.bottomnavigation.BottomNavigationView; +import com.google.android.material.navigation.NavigationBarView; import com.google.android.material.navigation.NavigationView; +import androidx.annotation.Nullable; import androidx.appcompat.widget.ActionMenuView; import androidx.appcompat.widget.Toolbar; import androidx.core.app.ActivityCompat; @@ -28,6 +32,12 @@ import androidx.appcompat.app.ActionBarDrawerToggle; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; +import androidx.navigation.NavController; +import androidx.navigation.NavDestination; +import androidx.navigation.Navigation; +import androidx.navigation.ui.AppBarConfiguration; +import androidx.navigation.ui.NavigationUI; + import android.text.InputType; import android.text.method.ScrollingMovementMethod; import android.util.Log; @@ -62,100 +72,33 @@ public class MainActivity extends AppCompatActivity { - final static private String line_separator = System.getProperty("line.separator"); - - private IdEntryDbHelper mDbHelper; - - private SharedPreferences.OnSharedPreferenceChangeListener mPrefListener; - - //database prepared statements - private SQLiteStatement sqlUpdateNote; - private SQLiteStatement sqlDeleteId; - private SQLiteStatement sqlUpdateChecked; - private SQLiteStatement sqlUpdateUserAndDate; - - private SparseArray mIds; - - //global variable to track matching order - private int mMatchingOrder; - - private String mListId; - - //pair mode vars - private String mPairCol; - private String mNextPairVal; - - private String mFileName = ""; - - private Toolbar navigationToolBar; - @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(org.phenoapps.verify.R.layout.activity_main); - - mIds = new SparseArray<>(); - - SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); - -final View auxInfo = findViewById(R.id.auxScrollView); -final View auxValue = findViewById(R.id.auxValueView); - - if (sharedPref.getBoolean(SettingsActivity.AUX_INFO, false)) { -auxInfo.setVisibility(View.VISIBLE); -auxValue.setVisibility(View.VISIBLE); - - } else { -auxInfo.setVisibility(View.GONE); -auxValue.setVisibility(View.GONE); -} - - mPrefListener = new SharedPreferences.OnSharedPreferenceChangeListener() { - @Override - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) { + setContentView(R.layout.activity_main); -if (sharedPreferences.getBoolean(SettingsActivity.AUX_INFO, false)) { -auxInfo.setVisibility(View.VISIBLE); -auxValue.setVisibility(View.VISIBLE); -} else { -auxInfo.setVisibility(View.GONE); -auxValue.setVisibility(View.GONE); -} - } - }; - - sharedPref.registerOnSharedPreferenceChangeListener(mPrefListener); - - if (!sharedPref.getBoolean("onlyLoadTutorialOnce", false)) { - launchIntro(); - SharedPreferences.Editor editor = sharedPref.edit(); - editor.putBoolean("onlyLoadTutorialOnce", true); - editor.apply(); - } else { - boolean tutorialMode = sharedPref.getBoolean(SettingsActivity.TUTORIAL_MODE, false); - - if (tutorialMode) - launchIntro(); - } - - mFileName = sharedPref.getString(SettingsActivity.FILE_NAME, ""); - - ActivityCompat.requestPermissions(this, VerifyConstants.permissions, VerifyConstants.PERM_REQ); + BottomNavigationView bottomNavigationView = (BottomNavigationView) findViewById(R.id.bottom_toolbar);; + NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment); + NavigationUI.setupWithNavController(bottomNavigationView, navController); + } - mNextPairVal = null; - mMatchingOrder = 0; - mPairCol = null; - initializeUIVariables(); + @Override + final public void onPause() { + super.onPause(); + } - mDbHelper = new IdEntryDbHelper(this); - loadSQLToLocal(); + @Override + public boolean onSupportNavigateUp() { + NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment); + return navController.navigateUp() || super.onSupportNavigateUp(); + } - if (mListId != null) - updateCheckedItems(); + public static void scanFile(Context ctx, File filePath) { + MediaScannerConnection.scanFile(ctx, new String[] { filePath.getAbsolutePath()}, null, null); } private void copyRawToVerify(File verifyDirectory, String fileName, int rawId) { @@ -183,888 +126,13 @@ private void copyRawToVerify(File verifyDirectory, String fileName, int rawId) { } } - public static void scanFile(Context ctx, File filePath) { - MediaScannerConnection.scanFile(ctx, new String[] { filePath.getAbsolutePath()}, null, null); - } - - private void prepareStatements() { - - final SQLiteDatabase db = mDbHelper.getWritableDatabase(); - try { - String updateNoteQuery = "UPDATE VERIFY SET note = ? WHERE " + mListId + " = ?"; - sqlUpdateNote = db.compileStatement(updateNoteQuery); - - String deleteIdQuery = "DELETE FROM VERIFY WHERE " + mListId + " = ?"; - sqlDeleteId = db.compileStatement(deleteIdQuery); - - String updateCheckedQuery = "UPDATE VERIFY SET color = 1 WHERE " + mListId + " = ?"; - sqlUpdateChecked = db.compileStatement(updateCheckedQuery); - - String updateUserAndDateQuery = - "UPDATE VERIFY SET user = ?, date = ?, scan_count = scan_count + 1 WHERE " + mListId + " = ?"; - sqlUpdateUserAndDate = db.compileStatement(updateUserAndDateQuery); - } catch(SQLiteException e) { - e.printStackTrace(); - } - } - - private void initializeUIVariables() { - - if (getSupportActionBar() != null){ - getSupportActionBar().setTitle("CheckList"); - getSupportActionBar().getThemedContext(); - getSupportActionBar().setHomeButtonEnabled(true); - } - - final EditText scannerTextView = ((EditText) findViewById(R.id.scannerTextView)); - scannerTextView.setSelectAllOnFocus(true); - scannerTextView.setOnKeyListener(new View.OnKeyListener() { - @Override - public boolean onKey(View v, int keyCode, KeyEvent event) { - - if (event.getAction() == KeyEvent.ACTION_DOWN) { - if (keyCode == KeyEvent.KEYCODE_ENTER) { - checkScannedItem(); - } - } - return false; - } - }); - - ListView idTable = ((ListView) findViewById(R.id.idTable)); - idTable.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE); -idTable.setOnItemClickListener(new AdapterView.OnItemClickListener() { - - @Override - public void onItemClick(AdapterView parent, View view, int position, long id) { -scannerTextView.setText(((TextView) view).getText().toString()); - scannerTextView.setSelection(scannerTextView.getText().length()); - scannerTextView.requestFocus(); - scannerTextView.selectAll(); - checkScannedItem(); - } - }); - -idTable.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { -@Override -public boolean onItemLongClick(AdapterView parent, View view, int position, long id) { -//get app settings -insertNoteIntoDb(((TextView) view).getText().toString()); -return true; -} - }); - - TextView valueView = (TextView) findViewById(R.id.valueView); - valueView.setMovementMethod(new ScrollingMovementMethod()); - - findViewById(org.phenoapps.verify.R.id.clearButton).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - scannerTextView.setText(""); - } - }); - } - - private synchronized void checkScannedItem() { - - SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(MainActivity.this); - int scanMode = Integer.valueOf(sharedPref.getString(SettingsActivity.SCAN_MODE_LIST, "-1")); -boolean displayAux = sharedPref.getBoolean(SettingsActivity.AUX_INFO, true); - - String scannedId = ((EditText) findViewById(org.phenoapps.verify.R.id.scannerTextView)) - .getText().toString(); - - if (mIds != null && mIds.size() > 0) { - //update database - exertModeFunction(scannedId); - - //view updated database - SQLiteDatabase db = mDbHelper.getReadableDatabase(); - - String table = IdEntryContract.IdEntry.TABLE_NAME; - String[] selectionArgs = new String[]{scannedId}; - Cursor cursor = db.query(table, null, mListId + "=?", selectionArgs, null, null, null); - - String[] headerTokens = cursor.getColumnNames(); - StringBuilder values = new StringBuilder(); - StringBuilder auxValues = new StringBuilder(); - if (cursor.moveToFirst()) { - for (String header : headerTokens) { - - if (!header.equals(mListId)) { - - final String val = cursor.getString( - cursor.getColumnIndexOrThrow(header) - ); - - if (header.equals("color") || header.equals("scan_count") || header.equals("date") - || header.equals("user") || header.equals("note")) { - if (header.equals("color")) continue; - else if (header.equals("scan_count")) auxValues.append("Number of scans"); - else if (header.equals("date")) auxValues.append("Date"); - else auxValues.append(header); - auxValues.append(" : "); - if (val != null) auxValues.append(val); - auxValues.append(line_separator); - } else { - values.append(header); - values.append(" : "); - if (val != null) values.append(val); - values.append(line_separator); - } - } - } - cursor.close(); -((TextView) findViewById(org.phenoapps.verify.R.id.valueView)).setText(values.toString()); -((TextView) findViewById(R.id.auxValueView)).setText(auxValues.toString()); -((EditText) findViewById(R.id.scannerTextView)).setText(""); - } else { - if (scanMode != 2) { - ringNotification(false); - } - } - } - } - - private Boolean checkIdExists(String id) { - SQLiteDatabase db = mDbHelper.getReadableDatabase(); - - final String table = IdEntryContract.IdEntry.TABLE_NAME; - final String[] selectionArgs = new String[] { id }; - final Cursor cursor = db.query(table, null, mListId + "=?", selectionArgs, null, null, null); - - if (cursor.moveToFirst()) { - cursor.close(); - return true; - } else { - cursor.close(); - return false; - } - } - - private synchronized void insertNoteIntoDb(@NonNull final String id) { - - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle("Enter a note for the given item."); - final EditText input = new EditText(this); - input.setInputType(InputType.TYPE_CLASS_TEXT); - builder.setView(input); - - builder.setPositiveButton("Save", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - String value = input.getText().toString(); - if (!value.isEmpty()) { - - final SQLiteDatabase db = mDbHelper.getWritableDatabase(); - - if (sqlUpdateNote != null) { - sqlUpdateNote.bindAllArgsAsStrings(new String[]{ - value, id - }); - sqlUpdateNote.executeUpdateDelete(); - } - } - } - }); - - builder.show(); - } - - private synchronized void exertModeFunction(@NonNull String id) { - - //get app settings - SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(MainActivity.this); - int scanMode = Integer.valueOf(sharedPref.getString(SettingsActivity.SCAN_MODE_LIST, "-1")); - - SQLiteDatabase db = mDbHelper.getWritableDatabase(); - - if (scanMode == 0 ) { //default mode - mMatchingOrder = 0; - ringNotification(checkIdExists(id)); - - } else if (scanMode == 1) { //order mode - final int tableIndex = getTableIndexById(id); - - if (tableIndex != -1) { - if (mMatchingOrder == tableIndex) { - mMatchingOrder++; - Toast.makeText(this, "Order matches id: " + id + " at index: " + tableIndex, Toast.LENGTH_SHORT).show(); - ringNotification(true); - } else { - Toast.makeText(this, "Scanning out of order!", Toast.LENGTH_SHORT).show(); - ringNotification(false); - } - } - } else if (scanMode == 2) { //filter mode, delete rows with given id - - mMatchingOrder = 0; - if (sqlDeleteId != null) { - sqlDeleteId.bindAllArgsAsStrings(new String[]{id}); - sqlDeleteId.executeUpdateDelete(); - } - updateFilteredArrayAdapter(id); - - } else if (scanMode == 3) { //if color mode, update the db to highlight the item - - mMatchingOrder = 0; - if (sqlUpdateChecked != null) { - sqlUpdateChecked.bindAllArgsAsStrings(new String[]{id}); - sqlUpdateChecked.executeUpdateDelete(); - } - } else if (scanMode == 4) { //pair mode - - mMatchingOrder = 0; - - if (mPairCol != null) { - - //if next pair id is waiting, check if it matches scanned id and reset mode - if (mNextPairVal != null) { - if (mNextPairVal.equals(id)) { - ringNotification(true); - Toast.makeText(this, "Scanned paired item: " + id, Toast.LENGTH_SHORT).show(); - } - mNextPairVal = null; - } else { //otherwise query for the current id's pair - String table = IdEntryContract.IdEntry.TABLE_NAME; - String[] columnsNames = new String[] { mPairCol }; - String selection = mListId + "=?"; - String[] selectionArgs = { id }; - Cursor cursor = db.query(table, columnsNames, selection, selectionArgs, null, null, null); - if (cursor.moveToFirst()) { - mNextPairVal = cursor.getString( - cursor.getColumnIndexOrThrow(mPairCol) - ); - } else mNextPairVal = null; - cursor.close(); - } - } - } - //always update user and datetime - final Calendar c = Calendar.getInstance(); - final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss", Locale.getDefault()); - - if (sqlUpdateUserAndDate != null) { //no db yet - String name = sharedPref.getString(SettingsActivity.NAME, ""); - sqlUpdateUserAndDate.bindAllArgsAsStrings(new String[]{ - name, - sdf.format(c.getTime()), - id - }); - sqlUpdateUserAndDate.executeUpdateDelete(); - } - - updateCheckedItems(); - } - - private synchronized void updateCheckedItems() { - - final SQLiteDatabase db = mDbHelper.getReadableDatabase(); - - //list of ideas to populate and update the view with - final HashSet ids = new HashSet<>(); - - final String table = IdEntryContract.IdEntry.TABLE_NAME; - final String[] columns = new String[] { mListId }; - final String selection = "color = 1"; - - try { - final Cursor cursor = db.query(table, columns, selection, null, null, null, null); - if (cursor.moveToFirst()) { - do { - String id = cursor.getString( - cursor.getColumnIndexOrThrow(mListId) - ); - - ids.add(id); - } while (cursor.moveToNext()); - } - cursor.close(); - } catch (SQLiteException e) { - e.printStackTrace(); - } - ListView idTable = (ListView) findViewById(org.phenoapps.verify.R.id.idTable); - for (int position = 0; position < idTable.getCount(); position++) { - - final String id = (idTable.getItemAtPosition(position)).toString(); - - if (ids.contains(id)) { - idTable.setItemChecked(position, true); - } else idTable.setItemChecked(position, false); - } - } - - private synchronized void loadSQLToLocal() { - - mIds = new SparseArray<>(); - - mDbHelper = new IdEntryDbHelper(this); - - final SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(MainActivity.this); - mListId = sharedPref.getString(SettingsActivity.LIST_KEY_NAME, null); - mPairCol = sharedPref.getString(SettingsActivity.PAIR_NAME, null); - - if (mListId != null) { - prepareStatements(); - loadBarcodes(); - buildListView(); - } - } - - private void loadBarcodes() { - - SQLiteDatabase db = mDbHelper.getReadableDatabase(); - try { - final String table = IdEntryContract.IdEntry.TABLE_NAME; - final Cursor cursor = db.query(table, null, null, null, null, null, null); - - if (cursor.moveToFirst()) { - do { - final String[] headers = cursor.getColumnNames(); - for (String header : headers) { - - final String val = cursor.getString( - cursor.getColumnIndexOrThrow(header) - ); - - if (header.equals(mListId)) { - mIds.append(mIds.size(), val); - } - } - } while (cursor.moveToNext()); - } - cursor.close(); - - } catch (SQLiteException e) { - e.printStackTrace(); - } - } - - private synchronized void askUserExportFileName() { - - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle("Choose name for exported file."); - final EditText input = new EditText(this); - - final Calendar c = Calendar.getInstance(); - final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()); - - int lastDot = mFileName.lastIndexOf('.'); - if (lastDot != -1) { - mFileName = mFileName.substring(0, lastDot); - } - input.setText("Verify_"+ sdf.format(c.getTime())); - input.setInputType(InputType.TYPE_CLASS_TEXT); - builder.setView(input); - - builder.setPositiveButton("Export", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int which) { - String value = input.getText().toString(); - mFileName = value; - final Intent i; - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) { - i = new Intent(Intent.ACTION_CREATE_DOCUMENT); - i.setType("*/*"); - i.putExtra(Intent.EXTRA_TITLE, value+".csv"); - startActivityForResult(Intent.createChooser(i, "Choose folder to export file."), VerifyConstants.PICK_CUSTOM_DEST); - }else{ - writeToExportPath(); - } - } - }); - builder.show(); - } - - public void writeToExportPath(){ - String value = mFileName; - - if (!value.isEmpty()) { - if (isExternalStorageWritable()) { - try { - File verifyDirectory = new File(Environment.getExternalStorageDirectory().getPath() + "/Verify"); - final File output = new File(verifyDirectory, value + ".csv"); - final FileOutputStream fstream = new FileOutputStream(output); - final SQLiteDatabase db = mDbHelper.getReadableDatabase(); - final String table = IdEntryContract.IdEntry.TABLE_NAME; - final Cursor cursor = db.query(table, null, null, null, null, null, null); - //final Cursor cursor = db.rawQuery("SElECT * FROM VERIFY", null); - - //first write header line - final String[] headers = cursor.getColumnNames(); - for (int i = 0; i < headers.length; i++) { - if (i != 0) fstream.write(",".getBytes()); - fstream.write(headers[i].getBytes()); - } - fstream.write(line_separator.getBytes()); - //populate text file with current database values - if (cursor.moveToFirst()) { - do { - for (int i = 0; i < headers.length; i++) { - if (i != 0) fstream.write(",".getBytes()); - final String val = cursor.getString( - cursor.getColumnIndexOrThrow(headers[i]) - ); - if (val == null) fstream.write("null".getBytes()); - else fstream.write(val.getBytes()); - } - fstream.write(line_separator.getBytes()); - } while (cursor.moveToNext()); - } - - cursor.close(); - fstream.flush(); - fstream.close(); - scanFile(MainActivity.this, output); - /*MediaScannerConnection.scanFile(MainActivity.this, new String[] {output.toString()}, null, new MediaScannerConnection.OnScanCompletedListener() { - @Override - public void onScanCompleted(String path, Uri uri) { - Log.v("scan complete", path); - } - });*/ - }catch (NullPointerException npe){ - npe.printStackTrace(); - Toast.makeText(this, "Error in opening the Specified file", Toast.LENGTH_LONG).show(); - } - catch (SQLiteException e) { - e.printStackTrace(); - Toast.makeText(MainActivity.this, "Error exporting file, is your table empty?", Toast.LENGTH_SHORT).show(); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException io) { - io.printStackTrace(); - } - } else { - Toast.makeText(MainActivity.this, - "External storage not writable.", Toast.LENGTH_SHORT).show(); - } - } else { - Toast.makeText(MainActivity.this, - "Must enter a file name.", Toast.LENGTH_SHORT).show(); - } - } - - public void writeToExportPath(Uri uri){ - - String value = mFileName; - - if (uri == null){ - Toast.makeText(this, "Unable to open the Specified file", Toast.LENGTH_LONG).show(); - return; - } - - if (!value.isEmpty()) { - if (isExternalStorageWritable()) { - try { - final File output = new File(uri.getPath()); - final OutputStream fstream = getContentResolver().openOutputStream(uri); - final SQLiteDatabase db = mDbHelper.getReadableDatabase(); - final String table = IdEntryContract.IdEntry.TABLE_NAME; - final Cursor cursor = db.query(table, null, null, null, null, null, null); - //final Cursor cursor = db.rawQuery("SElECT * FROM VERIFY", null); - - //first write header line - final String[] headers = cursor.getColumnNames(); - for (int i = 0; i < headers.length; i++) { - if (i != 0) fstream.write(",".getBytes()); - fstream.write(headers[i].getBytes()); - } - fstream.write(line_separator.getBytes()); - //populate text file with current database values - if (cursor.moveToFirst()) { - do { - for (int i = 0; i < headers.length; i++) { - if (i != 0) fstream.write(",".getBytes()); - final String val = cursor.getString( - cursor.getColumnIndexOrThrow(headers[i]) - ); - if (val == null) fstream.write("null".getBytes()); - else fstream.write(val.getBytes()); - } - fstream.write(line_separator.getBytes()); - } while (cursor.moveToNext()); - } - - cursor.close(); - fstream.flush(); - fstream.close(); - scanFile(MainActivity.this, output); - /*MediaScannerConnection.scanFile(MainActivity.this, new String[] {output.toString()}, null, new MediaScannerConnection.OnScanCompletedListener() { - @Override - public void onScanCompleted(String path, Uri uri) { - Log.v("scan complete", path); - } - });*/ - }catch (NullPointerException npe){ - npe.printStackTrace(); - Toast.makeText(this, "Error in opening the Specified file", Toast.LENGTH_LONG).show(); - } - catch (SQLiteException e) { - e.printStackTrace(); - Toast.makeText(MainActivity.this, "Error exporting file, is your table empty?", Toast.LENGTH_SHORT).show(); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException io) { - io.printStackTrace(); - } - } else { - Toast.makeText(MainActivity.this, - "External storage not writable.", Toast.LENGTH_SHORT).show(); - } - } else { - Toast.makeText(MainActivity.this, - "Must enter a file name.", Toast.LENGTH_SHORT).show(); - } - } - - //returns index of table with identifier = id, returns -1 if not found - private int getTableIndexById(String id) { - - ListView idTable = (ListView) findViewById(org.phenoapps.verify.R.id.idTable); - final int size = idTable.getAdapter().getCount(); - int ret = -1; - for (int i = 0; i < size; i++) { - final String temp = (String) idTable.getAdapter().getItem(i); - if (temp.equals(id)) { - ret = i; - break; //break out of for-loop early - } - } - - return ret; - } - - private void updateFilteredArrayAdapter(String id) { - - ListView idTable = (ListView) findViewById(org.phenoapps.verify.R.id.idTable); - //update id table array adapter - final ArrayAdapter updatedAdapter = new ArrayAdapter<>(this, org.phenoapps.verify.R.layout.row); - final int oldSize = idTable.getAdapter().getCount(); - - for (int i = 0; i < oldSize; i++) { - final String temp = (String) idTable.getAdapter().getItem(i); - if (!temp.equals(id)) updatedAdapter.add(temp); - } - idTable.setAdapter(updatedAdapter); - } - - private void ringNotification(boolean success) { - - final SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); - final boolean audioEnabled = sharedPref.getBoolean(SettingsActivity.AUDIO_ENABLED, true); - - if(success) { //ID found - if(audioEnabled) { - if (success) { - try { - int resID = getResources().getIdentifier("plonk", "raw", getPackageName()); - MediaPlayer chimePlayer = MediaPlayer.create(MainActivity.this, resID); - chimePlayer.start(); - - chimePlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { - public void onCompletion(MediaPlayer mp) { - mp.release(); - } - }); - } catch (Exception ignore) { - } - } - } - } - - if(!success) { //ID not found - ((TextView) findViewById(org.phenoapps.verify.R.id.valueView)).setText(""); - - if (audioEnabled) { - if(!success) { - try { - int resID = getResources().getIdentifier("error", "raw", getPackageName()); - MediaPlayer chimePlayer = MediaPlayer.create(MainActivity.this, resID); - chimePlayer.start(); - - chimePlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { - public void onCompletion(MediaPlayer mp) { - mp.release(); - } - }); - } catch (Exception ignore) { - } - } - } else { - if (!success) { - Toast.makeText(this, "Scanned ID not found", Toast.LENGTH_SHORT).show(); - } - } - } - } - - @Override - final public boolean onCreateOptionsMenu(Menu m) { - - final MenuInflater inflater = getMenuInflater(); - inflater.inflate(org.phenoapps.verify.R.menu.activity_main_toolbar, m); - - ActionMenuView bottomToolBar = (ActionMenuView) findViewById(R.id.bottom_toolbar); - Menu bottomMenu = bottomToolBar.getMenu(); - inflater.inflate(R.menu.activity_main_bottom_toolbar, bottomMenu); - - for (int i = 0; i < bottomMenu.size(); i++) { - bottomMenu.getItem(i).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem item) { - return onOptionsItemSelected(item); - } - }); - } - return true; - } - - @Override - final public boolean onOptionsItemSelected(MenuItem item) { - DrawerLayout dl = (DrawerLayout) findViewById(R.id.drawer_layout); - int actionCamera = R.id.action_camera; - int actionImport = R.id.action_import; - int actionHome = R.id.Home; - int actionCompare = R.id.Compare; - int actionSettings = R.id.Settings; - - if (item.getItemId() == actionImport){ - final SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(MainActivity.this); - final int scanMode = Integer.valueOf(sharedPref.getString(SettingsActivity.SCAN_MODE_LIST, "-1")); - final Intent i; - File verifyDirectory = new File(getExternalFilesDir(null), "/Verify"); - - File[] files = verifyDirectory.listFiles(); - - - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle("Select files from?"); - builder.setPositiveButton("Storage", - new DialogInterface.OnClickListener() - { - public void onClick(DialogInterface dialog, int id) - { - Intent i; - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) { - i = new Intent(Intent.ACTION_OPEN_DOCUMENT); - }else{ - i = new Intent(Intent.ACTION_GET_CONTENT); - } - i.setType("*/*"); - startActivityForResult(Intent.createChooser(i, "Choose file to import."), VerifyConstants.DEFAULT_CONTENT_REQ); - } - }); - - builder.setNegativeButton("Verify Directory", - new DialogInterface.OnClickListener() - { - public void onClick(DialogInterface dialog, int id) - { - - AlertDialog.Builder fileBuilder = new AlertDialog.Builder(MainActivity.this); - fileBuilder.setTitle("Select the sample file"); - final int[] checkedItem = {-1}; - String[] listItems = verifyDirectory.list(); - fileBuilder.setSingleChoiceItems(listItems, checkedItem[0],(fileDialog, which) -> { - checkedItem[0] = which; - - Intent i = new Intent(MainActivity.this, LoaderDBActivity.class); - i.setData(Uri.fromFile(files[which])); - startActivityForResult(i, VerifyConstants.LOADER_INTENT_REQ); - fileDialog.dismiss(); - }); - - fileBuilder.show(); - - } - }); - builder.show(); - } else if (item.getItemId() == android.R.id.home){ - dl.openDrawer(GravityCompat.START); - } - else if (item.getItemId() == actionHome){ - - } - else if ( item.getItemId() == actionCompare) { - final Intent compareIntent = new Intent(MainActivity.this, CompareActivity.class); - runOnUiThread(new Runnable() { - @Override public void run() { - startActivity(compareIntent); - } - }); - } else if (item.getItemId() == actionSettings) { - final Intent settingsIntent = new Intent(this, SettingsActivity.class); - startActivityForResult(settingsIntent, VerifyConstants.SETTINGS_INTENT_REQ); - } else if(item.getItemId() == actionCamera){ - final Intent cameraIntent = new Intent(this, ScanActivity.class); - startActivityForResult(cameraIntent, VerifyConstants.CAMERA_INTENT_REQ); - } - else{ - return super.onOptionsItemSelected(item); - } - return true; - } - - @Override - final protected void onActivityResult(int requestCode, int resultCode, Intent intent) { - - super.onActivityResult(requestCode, resultCode, intent); - - if (resultCode == RESULT_OK) { - - if (intent != null) { - switch (requestCode) { - case VerifyConstants.PICK_CUSTOM_DEST: - writeToExportPath(intent.getData()); - break; - case VerifyConstants.DEFAULT_CONTENT_REQ: - Intent i = new Intent(this, LoaderDBActivity.class); - i.setData(intent.getData()); - startActivityForResult(i, VerifyConstants.LOADER_INTENT_REQ); - break; - case VerifyConstants.LOADER_INTENT_REQ: - - mListId = null; - mPairCol = null; - mFileName = ""; - - if (intent.hasExtra(VerifyConstants.FILE_NAME)) - mFileName = intent.getStringExtra(VerifyConstants.FILE_NAME); - if (intent.hasExtra(VerifyConstants.LIST_ID_EXTRA)) - mListId = intent.getStringExtra(VerifyConstants.LIST_ID_EXTRA); - if (intent.hasExtra(VerifyConstants.PAIR_COL_EXTRA)) - mPairCol = intent.getStringExtra(VerifyConstants.PAIR_COL_EXTRA); - - SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(MainActivity.this); - final SharedPreferences.Editor editor = sharedPref.edit(); - - int scanMode = Integer.valueOf(sharedPref.getString(SettingsActivity.SCAN_MODE_LIST, "-1")); - - if (mPairCol != null) { - editor.putBoolean(SettingsActivity.DISABLE_PAIR, false); - if (scanMode != 4) showPairDialog(); - } else { - editor.putBoolean(SettingsActivity.DISABLE_PAIR, true); - } - - if (mPairCol == null && scanMode == 4) { - editor.putString(SettingsActivity.SCAN_MODE_LIST, "0"); - Toast.makeText(this, - "Switching to default mode, no pair ID found.", - Toast.LENGTH_SHORT).show(); - } - editor.putString(SettingsActivity.FILE_NAME, mFileName); - editor.putString(SettingsActivity.PAIR_NAME, mPairCol); - editor.putString(SettingsActivity.LIST_KEY_NAME, mListId); - editor.apply(); - - clearListView(); - loadSQLToLocal(); - updateCheckedItems(); - break; - } - - if (intent.hasExtra(VerifyConstants.CAMERA_RETURN_ID)) { - ((EditText) findViewById(org.phenoapps.verify.R.id.scannerTextView)) - .setText(intent.getStringExtra(VerifyConstants.CAMERA_RETURN_ID)); - checkScannedItem(); - } - } - } - } - - private void buildListView() { - - ListView idTable = (ListView) findViewById(org.phenoapps.verify.R.id.idTable); -ArrayAdapter idAdapter = -new ArrayAdapter<>(this, org.phenoapps.verify.R.layout.row); - int size = mIds.size(); - for (int i = 0; i < size; i++) { -idAdapter.add(this.mIds.get(this.mIds.keyAt(i))); - } -idTable.setAdapter(idAdapter); - } - - private void clearListView() { - - ListView idTable = (ListView) findViewById(org.phenoapps.verify.R.id.idTable); -final ArrayAdapter adapter = -new ArrayAdapter<>(this, org.phenoapps.verify.R.layout.row); - - idTable.setAdapter(adapter); -adapter.notifyDataSetChanged(); - } - - private void showPairDialog() { - - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle("Pair column selected, would you like to switch to Pair mode?"); - - builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - - SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(MainActivity.this); - SharedPreferences.Editor editor = sharedPref.edit(); - editor.putString(SettingsActivity.SCAN_MODE_LIST, "4"); - editor.apply(); - } - }); - - builder.setNegativeButton("No thanks", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - - } - }); - - builder.show(); - } - - @Override - final protected void onPostCreate(Bundle savedInstanceState) { - super.onPostCreate(savedInstanceState); - } - - @Override - final public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - } - - private void launchIntro() { - - new Thread(new Runnable() { - @Override - public void run() { - - // Launch app intro - final Intent i = new Intent(MainActivity.this, IntroActivity.class); - - runOnUiThread(new Runnable() { - @Override public void run() { - startActivity(i); - } - }); - - - } - }).start(); - } - - /* Checks if external storage is available for read and write */ static private boolean isExternalStorageWritable() { return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()); } - @Override - final public void onDestroy() { - mDbHelper.close(); - super.onDestroy(); - } @Override public void onRequestPermissionsResult(int resultCode, String[] permissions, int[] granted) { - super.onRequestPermissionsResult(resultCode, permissions, granted); boolean externalWriteAccept = false; if (resultCode == VerifyConstants.PERM_REQ) { @@ -1086,10 +154,4 @@ public void onRequestPermissionsResult(int resultCode, String[] permissions, int copyRawToVerify(verifyDirectory, "verify_pair_sample.csv", R.raw.verify_pair_sample); } } - - @Override - final public void onPause() { - super.onPause(); - } - } diff --git a/app/src/main/java/org/phenoapps/verify/SettingsActivity.java b/app/src/main/java/org/phenoapps/verify/SettingsActivity.java deleted file mode 100644 index d35764d..0000000 --- a/app/src/main/java/org/phenoapps/verify/SettingsActivity.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.phenoapps.verify; - -import android.os.Bundle; - -import androidx.appcompat.app.AppCompatActivity; -import android.view.MenuItem; - -public class SettingsActivity extends AppCompatActivity { - - public static String FILE_NAME = "org.phenoapps.verify.FILE_NAME"; - public static String INTRO_BUTTON = "org.phenoapps.verify.INTRO"; - - public static String ABOUT_BUTTON = "org.phenoapps.verify.ABOUT"; - - public static String SCAN_MODE_LIST = "org.phenoapps.verify.SCAN_MODE"; - public static String AUDIO_ENABLED = "org.phenoapps.verify.AUDIO_ENABLED"; - public static String TUTORIAL_MODE = "org.phenoapps.verify.TUTORIAL_MODE"; - public static String NAME = "org.phenoapps.verify.NAME"; - - public static String LIST_KEY_NAME = "org.phenoapps.verify.LIST_KEY_NAME"; - public static String PAIR_NAME = "org.phenoapps.verify.PAIR_NAME"; - public static String DISABLE_PAIR = "org.phenoapps.verify.DISABLE_PAIR"; - public static String AUX_INFO = "org.phenoapps.verify.AUX_INFO"; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - if(getSupportActionBar() != null){ - getSupportActionBar().setTitle(null); - getSupportActionBar().getThemedContext(); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - getSupportActionBar().setHomeButtonEnabled(true); - } - - getFragmentManager().beginTransaction() - .replace(android.R.id.content, new SettingsFragment()) - .commit(); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - - switch (item.getItemId()) { - case android.R.id.home: - setResult(RESULT_OK); - finish(); - return true; - default: - return super.onOptionsItemSelected(item); - } - } -} \ No newline at end of file diff --git a/app/src/main/java/org/phenoapps/verify/SettingsFragment.java b/app/src/main/java/org/phenoapps/verify/SettingsFragment.java index 0092384..26674e3 100644 --- a/app/src/main/java/org/phenoapps/verify/SettingsFragment.java +++ b/app/src/main/java/org/phenoapps/verify/SettingsFragment.java @@ -5,14 +5,28 @@ import android.content.SharedPreferences; import android.os.Build; import android.os.Bundle; -import android.preference.ListPreference; -import android.preference.Preference; -import android.preference.PreferenceFragment; import android.widget.Toast; +import androidx.preference.Preference; +import androidx.preference.ListPreference; +import androidx.preference.PreferenceFragmentCompat; + import java.util.prefs.Preferences; -public class SettingsFragment extends PreferenceFragment { +public class SettingsFragment extends PreferenceFragmentCompat { + + + public static final CharSequence INTRO_BUTTON = "org.phenoapps.verify.INTRO"; + public static final CharSequence ABOUT_BUTTON = "org.phenoapps.verify.ABOUT"; + public static String FILE_NAME = "org.phenoapps.verify.FILE_NAME"; + public static String SCAN_MODE_LIST = "org.phenoapps.verify.SCAN_MODE"; + public static String AUDIO_ENABLED = "org.phenoapps.verify.AUDIO_ENABLED"; + public static String TUTORIAL_MODE = "org.phenoapps.verify.TUTORIAL_MODE"; + public static String NAME = "org.phenoapps.verify.NAME"; + public static String LIST_KEY_NAME = "org.phenoapps.verify.LIST_KEY_NAME"; + public static String PAIR_NAME = "org.phenoapps.verify.PAIR_NAME"; + public static String DISABLE_PAIR = "org.phenoapps.verify.DISABLE_PAIR"; + public static String AUX_INFO = "org.phenoapps.verify.AUX_INFO"; private void showChangeLog() { @@ -30,12 +44,18 @@ private void showAboutDialog(Context ctx) public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - addPreferencesFromResource(org.phenoapps.verify.R.xml.preferences); + } + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + + setPreferencesFromResource(R.xml.preferences, rootKey); + final SharedPreferences sharedPrefs = super.getPreferenceManager().getSharedPreferences(); - ListPreference mode = (ListPreference) findPreference(SettingsActivity.SCAN_MODE_LIST); - Preference introButton = (Preference) findPreference(SettingsActivity.INTRO_BUTTON); - Preference aboutButton = (Preference) findPreference(SettingsActivity.ABOUT_BUTTON); + ListPreference mode = findPreference(SCAN_MODE_LIST); + Preference introButton = findPreference(INTRO_BUTTON); + Preference aboutButton = findPreference(ABOUT_BUTTON); aboutButton.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { @Override @@ -68,7 +88,7 @@ public void run() { @Override public boolean onPreferenceChange(Preference preference, Object o) { if (o.equals("4") && - sharedPrefs.getBoolean(SettingsActivity.DISABLE_PAIR, false)) { + sharedPrefs.getBoolean(DISABLE_PAIR, false)) { ((ListPreference) preference).setValue("0"); Toast.makeText(getActivity(), "Pair mode cannot be used without setting a pair ID.", diff --git a/app/src/main/res/drawable/bottom_nav_color.xml b/app/src/main/res/drawable/bottom_nav_color.xml new file mode 100644 index 0000000..c6fc209 --- /dev/null +++ b/app/src/main/res/drawable/bottom_nav_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout-land/activity_main.xml b/app/src/main/res/layout-land/activity_main.xml index c483435..88ac3ed 100644 --- a/app/src/main/res/layout-land/activity_main.xml +++ b/app/src/main/res/layout-land/activity_main.xml @@ -1,118 +1,25 @@ - - - + android:layout_height="match_parent" + android:focusable="true" /> - - - - -