ECn Categories > Stuck Progress Notification (SPN)
This ECn type is exhibited when a progress notication gets stuck in the GUI (not necessarily blocking the app) because of a connection problem.
Amount of Issues | App List |
---|---|
14 | (A2) Wire, (A10) OsmAnd, (A23) Prey, (A31) OpenWeather, (A32) Cannonball, (A36) Stepik, (A39) Habitica, (A46) Open Food, (A49) PocketHub for GitHub |
Examples
PocketHub
The following code snippets show the classes and files that are involved in the generation of the previuos issue.
To start in the following snippet we can see the menu item that the user clicks at the first second of the video, this menu item has an id defined at line 21.
app/src/main/res/menu/activity_login.xml
<item
21. android:id="@+id/m_login"
app:showAsAction="always"
android:title="@string/log_in"/>
Now that we know the id of the menu item we can search in the class that manages the event, where the id is used. Following the android schema for menu usage we have to look in the “onCreateOptionsMenu” that the layour used is the same that the one that defines our menu item.
app/src/main/java/com/github/pockethub/android/accounts/LoginActivity.java
@Override
public boolean onCreateOptionsMenu(Menu optionMenu) {
251. getMenuInflater().inflate(R.menu.activity_login, optionMenu);
return true;
}
Aditionally, we have to search in “onOptionsItemSelected” what is the action assigned to the menu item. As we can see at lines 208 and 209, once it is clicked the “handleLogin” method is called.
app/src/main/java/com/github/pockethub/android/accounts/LoginActivity.java
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.m_login:
handleLogin();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
But from the implementation that can be seen in the following snippet the “handleLogin” method only calls “openLoginInBrowser” method.
app/src/main/java/com/github/pockethub/android/accounts/LoginActivity.java
public void handleLogin() {
178. openLoginInBrowser();
}
Now we have arrived to the main method of the event flow in this class, as we can see at betwwen lines 183 to 190 and url is build, but the important of this method happen between lines 192 to 194 where the url is send to an activity in charge of managing the login process using the url already created.
app/src/main/java/com/github/pockethub/android/accounts/LoginActivity.java
private void openLoginInBrowser() {
String initialScope = "user,public_repo,repo,delete_repo,notifications,gist";
HttpUrl.Builder url = new HttpUrl.Builder()
.scheme("https")
.host(OAUTH_HOST)
.addPathSegment("login")
.addPathSegment("oauth")
.addPathSegment("authorize")
.addQueryParameter("client_id", getString(R.string.github_client))
.addQueryParameter("scope", initialScope);
192. Intent intent = new Intent(this, LoginWebViewActivity.class);
193. intent.putExtra(INTENT_EXTRA_URL, url.toString());
194. startActivityForResult(intent, WEBVIEW_REQUEST_CODE);
}
Finally when the event flow arrives to this class, on the “onCreate” method the webview that manages the url received via intend extra is initialized. First a dialog is created with the text “Loading…” that can be seen at second 13 of the video. It is worth noting that at line 56 in the progress assign a “true” value is send, this allows the library used for the dialogs to know that this progress dialog will not have a intermediate state, so the the loading circle will turn while the dialog is shown.
app/src/main/java/com/github/pockethub/android/accounts/LoginWebViewActivity.java
webView.setWebViewClient(new WebViewClient() {
MaterialDialog dialog = new MaterialDialog.Builder(LoginWebViewActivity.this)
.content(R.string.loading)
56. .progress(true, 0)
.build();
As part of the webview initialization, some method have to be override in order to work. First, we have “onPageStarted” that will be called when the url loading process is started, in this specific case once the wep page loading starts the dialog already created is shown.
app/src/main/java/com/github/pockethub/android/accounts/LoginWebViewActivity.java
@Override
public void onPageStarted(android.webkit.WebView view, String url, Bitmap favicon) {
61. dialog.show();
}
Second, we have “onPageFinished” method that is called when the web page loading process end, in this specific case once the web page ends its loading the dialog that says loading is dismissed.
app/src/main/java/com/github/pockethub/android/accounts/LoginWebViewActivity.java
@Override
public void onPageFinished(android.webkit.WebView view, String url) {
66. dialog.dismiss();
}
Third, we have “shouldOverrideurlLoading” method that is called when inside of the loaded web page an anchor to other web page is activated, so there is a new url to be displayed inside the webView. In this specific case this method is called when the user already fill the form and click in “sign in” button. It is worth nothing that this method has to return a boolean value to know if the event is going to be managed in the existent webView or if it will be managed on the host application.
app/src/main/java/com/github/pockethub/android/accounts/LoginWebViewActivity.java
@Override
public boolean shouldOverrideUrlLoading(android.webkit.WebView view,
WebResourceRequest request) {
80. return overrideOAuth(request.getUrl())
81. || super.shouldOverrideUrlLoading(view, request);
}
To end this event flow, when the url is changed the “shouldOverrideUrlLoading” call overrideOAuth. This method verifies if the user clicks on the “sign in” button or in oen of the other links that are displayed in the webpage. If the user click in other link the webview manages the event and shos the new webpage. If the user clicks in the “sign in” button the event is managed by the host application and the already explained method will be called. In specific the “onPageStarted” method will be called while due to connectionless state the “onPageFinished” method will not.
app/src/main/java/com/github/pockethub/android/accounts/LoginWebViewActivity.java
private boolean overrideOAuth(Uri uri) {
85. if (uri.getScheme().equals(getString(R.string.github_oauth_scheme))) {
Intent data = new Intent();
data.setData(uri);
setResult(RESULT_OK, data);
finish();
90. return true;
}
return false;
}