Skip to content

Commit

Permalink
Add error connection activity with native layout and spinner for Weview
Browse files Browse the repository at this point in the history
  • Loading branch information
mrsarm committed Mar 19, 2021
1 parent 2749d4d commit aa7091d
Show file tree
Hide file tree
Showing 10 changed files with 319 additions and 2 deletions.
7 changes: 6 additions & 1 deletion src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,18 @@
<activity android:name="UpgradingActivity"
android:screenOrientation="portrait"
android:configChanges="orientation|screenSize"/>
<activity android:name="ConnectionErrorActivity"
android:screenOrientation="portrait"
android:configChanges="orientation|screenSize"
android:launchMode="singleTop"/>
<activity android:name="FreeSpaceWarningActivity"
android:screenOrientation="portrait"/>
<activity android:name="SettingsDialogActivity"
android:screenOrientation="portrait"/>
<activity android:name="RequestPermissionActivity"
android:screenOrientation="portrait"/>
<activity android:name="AppUrlIntentActivity" android:launchMode="singleInstance">
<activity android:name="AppUrlIntentActivity"
android:launchMode="singleInstance">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package org.medicmobile.webapp.mobile;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.widget.Toast;

/**
* Base class for activities that when back is pressed
* two times the app closes.
*
* When the user press back for the first time, a message
* defined in the `R.string.backToExit` string is shown
* explaining that it has to press back one more time. The
* message can be customized in the intent with the extended
* data "backPressedMessage"
* (calling `intent.putExtra("backPressedMessage", "...")`).
*
* Also the opposite action can be configured: the app
* not closing nor the activity when the user press
* back one or more times: to do so the `Intent` used to launch
* the activity needs to be set with the extended data "isClosable"
* to `false` (calling `intent.putExtra("isClosable", false)`).
* No message is shown to the user when back is pressed unless
* the extended data "backPressedMessage" is also set with the
* desired message.
*/
public abstract class ClosableAppActivity extends Activity {

private static final int WAIT_MILLIS = 2 * 1000; // Back need to be pressed 2 times before this time

private boolean closeableApp = true; // if true, back pressing 2 times close the app
private boolean backToExitPressedOnce = false; // whether back was pressed the last WAIT_MILLIS
private String backPressedMessage = null; // Customized message to show when back is pressed

@Override public void onBackPressed() {
if (closeableApp) {
if (backToExitPressedOnce) {
finishAffinity();
return;
}
backToExitPressedOnce = true;

toastMessage();

new Handler().postDelayed(new Runnable() {
@Override public void run() {
// After WAIT_MILLIS clean the back pressed history
backToExitPressedOnce = false;
}
}, WAIT_MILLIS);
} else {
// Back pressed events won't close the app nor close the activity
toastMessage();
}
}

@Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent i = getIntent();
closeableApp = i.getBooleanExtra("isClosable", true); // not closable (the default value is true)
backPressedMessage = i.getStringExtra("backPressedMessage"); // default null
}

private void toastMessage() {
if (closeableApp) {
if (backPressedMessage != null) {
Toast.makeText(this, backPressedMessage, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, R.string.backToExit, Toast.LENGTH_SHORT).show();
}
} else if (backPressedMessage != null) {
Toast.makeText(this, backPressedMessage, Toast.LENGTH_SHORT).show();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package org.medicmobile.webapp.mobile;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.view.Window;

import static android.view.View.VISIBLE;
import static android.view.View.GONE;
import static org.medicmobile.webapp.mobile.MedicLog.trace;


/**
* Activity displayed to catch connection errors and give the user
* the chance to retry.
*
* NOTE: it only catch connection errors when the web container
* tries to load a new page or reload the current one.
* Errors when the webapp does ajax calls are caught by
* the webapp itself.
*/
public class ConnectionErrorActivity extends ClosableAppActivity {

@Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.connection_error);

// If a page load finished and the activity is still spinning -> close
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override public void onReceive(Context context, Intent intent) {
if ("onPageFinished".equals(intent.getAction()) && isSpinning()) {
unregisterReceiver(this);
finish();
}
}
};
registerReceiver(broadcastReceiver, new IntentFilter("onPageFinished"));
}

@Override protected void onNewIntent(Intent intent) {
showMessageLayout();
}

public void onClickRetry(View view) {
trace(this, "onClickRetry()");
sendBroadcast(new Intent("retryConnection"));
showSpinnerLayout();
}

// Toggle layout components: hide the message layout
// and display the spinner layout
private void showSpinnerLayout() {
setLayoutsVisibility(GONE, VISIBLE);
}

// Toggle layout components: hide the spinner layout
// and display the message layout
private void showMessageLayout() {
setLayoutsVisibility(VISIBLE, GONE);
}

// Set visibility for the Internet connection error layout
// and the spinner layout
private void setLayoutsVisibility(int messageLayoutVisibility, int spinnerVisibility) {
View messageLayout = getMessageLayout();
messageLayout.setVisibility(messageLayoutVisibility);
View spinnerLayout = getSpinnerLayout();
spinnerLayout.setVisibility(spinnerVisibility);
}

private View getMessageLayout() {
return findViewById(R.id.connErrorMessageLayout);
}

private View getSpinnerLayout() {
return findViewById(R.id.connErrorSpinnerLayout);
}

private boolean isSpinning() {
return getSpinnerLayout().getVisibility() == VISIBLE;
}
}
13 changes: 13 additions & 0 deletions src/main/java/org/medicmobile/webapp/mobile/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.webkit.WebResourceError;

import org.json.JSONException;
import org.json.JSONObject;

import static android.webkit.WebViewClient.*;
import static org.medicmobile.webapp.mobile.BuildConfig.APPLICATION_ID;
import static org.medicmobile.webapp.mobile.BuildConfig.DEBUG;
import static org.medicmobile.webapp.mobile.BuildConfig.VERSION_NAME;
Expand Down Expand Up @@ -77,4 +79,15 @@ static void restartApp(Context context) {
context.startActivity(intent);
Runtime.getRuntime().exit(0);
}

static boolean isConnectionError(WebResourceError error) {
switch (error.getErrorCode()) {
case ERROR_HOST_LOOKUP:
case ERROR_PROXY_AUTHENTICATION:
case ERROR_CONNECT:
case ERROR_TIMEOUT:
return true;
}
return false;
}
}
77 changes: 77 additions & 0 deletions src/main/res/layout/connection_error.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="16dp"
android:paddingRight="16dp">


<RelativeLayout
android:id="@+id/connErrorMessageLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">

<TextView
android:id="@+id/connErrorTitleText"
style="@android:style/Widget.DeviceDefault.Light.TextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="140dp"
android:padding="20dp"
android:text="@string/connErrorTitle"
android:textSize="20sp"
android:textStyle="bold" />

<TextView
android:id="@+id/connErrorMessageText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/connErrorTitleText"
android:padding="20dp"
android:text="@string/connErrorMessage"
android:textSize="18sp" />

<LinearLayout
android:id="@+id/connErrorButtons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/connErrorMessageText"
android:layout_marginTop="20dp"
android:paddingLeft="20dp"
android:paddingRight="20dp"
android:paddingBottom="20dp">

<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />

<Button
android:id="@+id/connErrorRetry"
style="@style/Widget.AppCompat.Button.Borderless.Blue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClickRetry"
android:text="@string/connErrorRetry" />
</LinearLayout>
</RelativeLayout>

<RelativeLayout
android:id="@+id/connErrorSpinnerLayout"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:visibility="gone">

<ProgressBar
android:id="@+id/progressBarIcon"
style="?android:attr/progressBarStyleLarge"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:contentDescription="@string/loadingIconDescription"
android:padding="20dp" />
</RelativeLayout>

</RelativeLayout>
7 changes: 7 additions & 0 deletions src/main/res/values-es/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,11 @@
<string name="loadingIconDescription">Cargando…</string>
<string name="upgradingTitle">Actualizando la app</string>
<string name="upgradingMessage">Estás actualizando a la última versión. Por favor aguarda mientras tus datos son migrados.</string>

<string name="connErrorTitle">No hay Conexión a Internet</string>
<string name="connErrorMessage">Parece que no estás conectado a Internet. Por favor chequeá tu conexión y volvé a intentar.</string>
<string name="connErrorRetry">REINTENTAR</string>

<string name="backToExit">Por favor presione hacia atrás de nuevo para salir</string>
<string name="waitMigration">Por favor espere a que el proceso de migración haya finalizado</string>
</resources>
7 changes: 7 additions & 0 deletions src/main/res/values-fr/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,11 @@
<string name="loadingIconDescription">Chargement en cours…</string>
<string name="upgradingTitle">Mise à jour de votre application</string>
<string name="upgradingMessage">Vous passez à la nouvelle version. Veuillez patienter pendant la preparation de vos données.</string>

<string name="connErrorTitle">Pas de connexion Internet</string>
<string name="connErrorMessage">Vous ne semblez pas connecté à Internet. Veuillez vérifier votre connexion et réessayer.</string>
<string name="connErrorRetry">RECOMMENCEZ</string>

<string name="backToExit">Veuillez appuyer à nouveau pour quitter</string>
<string name="waitMigration">Veuillez attendre la fin du processus de migration</string>
</resources>
7 changes: 7 additions & 0 deletions src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,11 @@
<string name="loadingIconDescription">Loading…</string>
<string name="upgradingTitle">Upgrading your app</string>
<string name="upgradingMessage">You\'re upgrading to the latest version. Please wait while your data is being migrated.</string>

<string name="connErrorTitle">No Internet Connection</string>
<string name="connErrorMessage">You don\'t seem to be connected to the Internet. Please check your connection and try again.</string>
<string name="connErrorRetry">RETRY</string>

<string name="backToExit">Please press back again to exit</string>
<string name="waitMigration">Please wait until the migration process is finished</string>
</resources>
Loading

0 comments on commit aa7091d

Please sign in to comment.