diff --git a/.gitignore b/.gitignore index f24fa06b..8f04c3b1 100644 --- a/.gitignore +++ b/.gitignore @@ -60,9 +60,14 @@ fastlane/test_output fastlane/readme.md app/release/output.json -.DS_Store # Custom product flavours *custom-flavours.gradle *.aab + +#DS_Store files +*.DS_Store +.DS_Store +./.DS_Store +./.git/.DS_Store diff --git a/README.md b/README.md index cc418862..a03f229f 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ Parameters: * ```RAR_PASSWORD``` represents the password to be used for the offline extract. * ```SHOW_CONTROL_NUMBER_MENU``` allow to show or hide the Control Number menu item in case the implementation does not implement the ePayment module. * ```app_name_policies``` is a resource string allowing to change the name of the application. +* ```sentry_dsn``` allow to define the sentry dsn of your project where error and exception events from your application will be sent Escape procedures can be configured and language resource files can be changed. Please follow the ```sourceSets``` record. Look in ```app\src\demo``` folder for an example. diff --git a/app/build.gradle b/app/build.gradle index c17e343c..48fcbd56 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -52,6 +52,7 @@ android { buildConfigField "boolean", "IS_PAYMENT_ENABLED", 'false' resValue "string", "app_name_policies", "Policies" resValue "string", "ReleaseDateValue", getDate() + resValue "string", "sentry_dsn", "" } buildTypes { release { @@ -263,6 +264,7 @@ dependencies { // unit tests testImplementation 'junit:junit:4.13.2' + implementation 'io.sentry:sentry-android:8.25.0' testImplementation 'org.mockito:mockito-core:5.5.0' testImplementation 'org.robolectric:robolectric:4.11.1' } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5a88ad6d..ad266e97 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -63,6 +63,8 @@ android:resource="@xml/paths" /> + + policies = familyPolicyFromJSONObject(family.getUuid(), policiesArray); new UpdateFamily().execute(family, policies); } catch (Exception e) { + Sentry.captureException(e); e.printStackTrace(); enrolMessages.add(Objects.requireNonNullElse(e.getMessage(), "Something went wrong updating the family")); return -400; @@ -3582,9 +3591,9 @@ protected void onPostExecute(Boolean aBoolean) { } } - protected void DeleteUploadedData(final int FamilyId, ArrayList FamilyIDs, int CallerId) { - if (FamilyIDs.size() == 0) { - FamilyIDs = new ArrayList<>() {{ + private void DeleteUploadedData(final int FamilyId, ArrayList FamilyIDs, int CallerId) { + if (FamilyIDs.isEmpty()) { + FamilyIDs = new ArrayList() {{ add(String.valueOf(FamilyId)); }}; } @@ -3675,6 +3684,7 @@ public void uploadFeedbacks() { MoveFile(xmlFiles[i], 1); MoveFile(jsonFiles[i], 1); } catch (Exception e) { + Sentry.captureException(e); e.printStackTrace(); if ( e instanceof HttpException && @@ -3913,6 +3923,7 @@ public void downloadMasterData() { ((MainActivity) activity).ShowEnrolmentOfficerDialog(); }); } catch (JSONException e) { + Sentry.captureException(e); Log.e("MASTERDATA", "Error while parsing master data", e); } catch (UserException e) { Log.e("MASTERDATA", "Error while downloading master data", e); @@ -3935,6 +3946,7 @@ public void importMasterData(String data) throws JSONException, UserException { try { processOldFormat(new JSONArray(data)); } catch (JSONException e) { + Sentry.captureException(e); try { processNewFormat(new JSONObject(data)); } catch (JSONException e2) { @@ -3949,6 +3961,7 @@ public void startDownloadingMasterData() throws JSONException, UserException, Us try { importMasterData(new FetchMasterData().execute()); } catch (Exception e) { + Sentry.captureException(e); if (e instanceof UserNotAuthenticatedException) { throw (UserNotAuthenticatedException) e; } @@ -4066,6 +4079,7 @@ private void processOldFormat(@NonNull JSONArray masterData) throws UserExceptio insertPhoneDefaults(PhoneDefaults); insertGenders(Genders); } catch (JSONException e) { + Sentry.captureException(e); e.printStackTrace(); throw new UserException(activity.getResources().getString(R.string.DownloadMasterDataFailed), e); } @@ -4573,6 +4587,7 @@ public void SaveInsureePolicy(int InsureId, int FamilyId, Boolean Activate, int ExpiryDate = PolicyObject2.getString("ExpiryDate"); EnrollDate = PolicyObject2.getString("EnrollDate"); } catch (JSONException e) { + Sentry.captureException(e); e.printStackTrace(); } values.put("InsureePolicyId", MaxInsureePolicyId); diff --git a/app/src/main/java/org/openimis/imispolicies/MainActivity.java b/app/src/main/java/org/openimis/imispolicies/MainActivity.java index 9298d82a..2165a808 100644 --- a/app/src/main/java/org/openimis/imispolicies/MainActivity.java +++ b/app/src/main/java/org/openimis/imispolicies/MainActivity.java @@ -71,6 +71,7 @@ import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import org.openimis.imispolicies.network.exception.HttpException; import org.openimis.imispolicies.network.exception.UserNotAuthenticatedException; import org.openimis.imispolicies.tools.LanguageManager; import org.openimis.imispolicies.tools.Log; @@ -88,6 +89,8 @@ import java.io.OutputStream; import java.lang.ref.WeakReference; +import io.sentry.Sentry; + public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener { @@ -161,6 +164,7 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (f.exists() || f.createNewFile()) new FileOutputStream(f).write(bytes); } catch (IOException e) { + Sentry.captureException(e); e.printStackTrace(); } ShowDialogTex2(); @@ -230,100 +234,100 @@ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permis protected void onCreate(Bundle savedInstanceState) { global = (Global) getApplicationContext(); super.onCreate(savedInstanceState); - instance = this; - setContentView(R.layout.activity_main); - SQLHandler sqlHandler = new SQLHandler(this); - sqlHandler.isPrivate = true; - //Set the Image folder path - global.setImageFolder(global.getSubdirectory("Images")); - //Check if database exists - File database = global.getDatabasePath(SQLHandler.DBNAME); - if (!database.exists()) { - sqlHandler.getReadableDatabase(); - if (copyDatabase(this)) { - Toast.makeText(this, "Copy database success", Toast.LENGTH_SHORT).show(); - } else { - Toast.makeText(this, "Copy database failed", Toast.LENGTH_SHORT).show(); - return; - } - } else - sqlHandler.getReadableDatabase(); - - //Create image folder - createImageFolder(); - - Toolbar toolbar = findViewById(R.id.toolbar); - setSupportActionBar(toolbar); - - FloatingActionButton fab = findViewById(R.id.fab); - fab.setOnClickListener(view -> Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) - .setAction("Action", null).show()); - - DrawerLayout drawer = findViewById(R.id.drawer_layout); - ActionBarDrawerToggle toggle = new ActionBarDrawerToggle( - this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); - //noinspection deprecation - drawer.setDrawerListener(toggle); - toggle.syncState(); - - navigationView = findViewById(R.id.nav_view); + try { + instance = this; + setContentView(R.layout.activity_main); + SQLHandler sqlHandler = new SQLHandler(this); + sqlHandler.isPrivate = true; + //Set the Image folder path + global.setImageFolder(global.getSubdirectory("Images")); + //Check if database exists + File database = global.getDatabasePath(SQLHandler.DBNAME); + if (!database.exists()) { + sqlHandler.getReadableDatabase(); + if (copyDatabase(this)) { + Toast.makeText(this, "Copy database success", Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(this, "Copy database failed", Toast.LENGTH_SHORT).show(); + return; + } + } else + sqlHandler.getReadableDatabase(); + + //Create image folder + createImageFolder(); + + Toolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + + FloatingActionButton fab = findViewById(R.id.fab); + fab.setOnClickListener(view -> Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) + .setAction("Action", null).show()); + + DrawerLayout drawer = findViewById(R.id.drawer_layout); + ActionBarDrawerToggle toggle = new ActionBarDrawerToggle( + this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); + //noinspection deprecation + drawer.setDrawerListener(toggle); + toggle.syncState(); + + navigationView = findViewById(R.id.nav_view); + + navigationView.setNavigationItemSelectedListener(this); + wv = findViewById(R.id.webview); + WebSettings settings = wv.getSettings(); + wv.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY); + settings.setJavaScriptEnabled(true); + //noinspection deprecation + settings.setRenderPriority(WebSettings.RenderPriority.HIGH); + settings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); + settings.setDomStorageEnabled(true); + settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN); + settings.setUseWideViewPort(true); + settings.setSaveFormData(true); + settings.setAllowFileAccess(true); + //noinspection deprecation + settings.setEnableSmoothTransition(true); + settings.setLoadWithOverviewMode(true); + wv.addJavascriptInterface(new ClientAndroidInterface(this), "Android"); + + //Register for context acquire_menu + registerForContextMenu(wv); - navigationView.setNavigationItemSelectedListener(this); - wv = findViewById(R.id.webview); - WebSettings settings = wv.getSettings(); - wv.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY); - settings.setJavaScriptEnabled(true); - //noinspection deprecation - settings.setRenderPriority(WebSettings.RenderPriority.HIGH); - settings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); - settings.setDomStorageEnabled(true); - settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN); - settings.setUseWideViewPort(true); - settings.setSaveFormData(true); - settings.setAllowFileAccess(true); - //noinspection deprecation - settings.setEnableSmoothTransition(true); - settings.setLoadWithOverviewMode(true); - wv.addJavascriptInterface(new ClientAndroidInterface(this), "Android"); - - //Register for context acquire_menu - registerForContextMenu(wv); - - wv.loadUrl("file:///android_asset/pages/Home.html"); - wv.setWebViewClient(new MyWebViewClient(MainActivity.this)); - - wv.setWebChromeClient(new WebChromeClient() { - @Override - public void onReceivedTitle(WebView view, String title) { - super.onReceivedTitle(view, title); - //noinspection ConstantConditions - getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE); - getSupportActionBar().setSubtitle(title); + wv.loadUrl("file:///android_asset/pages/Home.html"); + wv.setWebViewClient(new MyWebViewClient(MainActivity.this)); + + wv.setWebChromeClient(new WebChromeClient() { + @Override + public void onReceivedTitle(WebView view, String title) { + super.onReceivedTitle(view, title); + //noinspection ConstantConditions + getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE); + getSupportActionBar().setSubtitle(title); + } + }); + NavigationView navigationView = findViewById(R.id.nav_view); + View headerview = navigationView.getHeaderView(0); + Login = headerview.findViewById(R.id.tvLogin); + OfficerName = headerview.findViewById(R.id.tvOfficerName); + + Login.setOnClickListener(v -> { + wv.loadUrl("file:///android_asset/pages/Login.html?s=3"); + drawer.closeDrawer(GravityCompat.START); + SetLoggedIn(); + }); + ca = new ClientAndroidInterface(this); + if (ca.isMasterDataAvailable() > 0) { + loadLanguages(); } - }); - NavigationView navigationView = findViewById(R.id.nav_view); - View headerview = navigationView.getHeaderView(0); - Login = headerview.findViewById(R.id.tvLogin); - OfficerName = headerview.findViewById(R.id.tvOfficerName); - - Login.setOnClickListener(v -> { - wv.loadUrl("file:///android_asset/pages/Login.html?s=3"); - drawer.closeDrawer(GravityCompat.START); - SetLoggedIn(); - }); - ca = new ClientAndroidInterface(this); - if (ca.isMasterDataAvailable() > 0) { - loadLanguages(); - } - - - navigationView.setCheckedItem(R.id.nav_home); - - if (checkRequirements()) { - onAllRequirementsMet(); + navigationView.setCheckedItem(R.id.nav_home); + if (checkRequirements()) { + onAllRequirementsMet(); + } + setVisibilityOfPaymentMenu(); + } catch (Exception e) { + Sentry.captureException(e); } - - setVisibilityOfPaymentMenu(); } private void setVisibilityOfPaymentMenu() { @@ -508,6 +512,7 @@ public void ShowEnrolmentOfficerDialog() { //ShowDialogTex(); } } catch (JSONException e) { + Sentry.captureException(e); e.printStackTrace(); } }) @@ -567,6 +572,7 @@ public void ShowDialogTex2() { ConfirmDialogPage((f.getName())); } } catch (Exception e) { + Sentry.captureException(e); e.getMessage(); } })