Notification auto dismisses when clicked. If no scheme is specified in URLs, http is automatically added to the front. If non HTTP schemes are used, a warning is shown.

This commit is contained in:
Aidan Follestad 2016-07-31 13:23:21 -05:00
commit ad5337ef50
7 changed files with 84 additions and 7 deletions

View file

@ -8,8 +8,8 @@ android {
applicationId "com.afollestad.nocknock" applicationId "com.afollestad.nocknock"
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 24 targetSdkVersion 24
versionCode 5 versionCode 6
versionName "0.1.0.1" versionName "0.1.0.2"
jackOptions { jackOptions {
enabled true enabled true

View file

@ -135,6 +135,7 @@ public class CheckService extends Service {
.setSmallIcon(R.drawable.ic_notification) .setSmallIcon(R.drawable.ic_notification)
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher)) .setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher))
.setPriority(Notification.PRIORITY_HIGH) .setPriority(Notification.PRIORITY_HIGH)
.setAutoCancel(true)
.setDefaults(Notification.DEFAULT_VIBRATE) .setDefaults(Notification.DEFAULT_VIBRATE)
.build(); .build();
nm.notify(site.url, NOTI_ID, noti); nm.notify(site.url, NOTI_ID, noti);
@ -150,6 +151,8 @@ public class CheckService extends Service {
Inquiry.init(this, MainActivity.DB_NAME, 1); Inquiry.init(this, MainActivity.DB_NAME, 1);
isRunning(true); isRunning(true);
Bridge.config()
.defaultHeader("User-Agent", getString(R.string.app_name) + " (Android)");
new Thread(() -> { new Thread(() -> {
final Query<ServerModel, Integer> query = Inquiry.get() final Query<ServerModel, Integer> query = Inquiry.get()

View file

@ -3,6 +3,7 @@ package com.afollestad.nocknock.ui;
import android.animation.Animator; import android.animation.Animator;
import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorListenerAdapter;
import android.content.Intent; import android.content.Intent;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.design.widget.TextInputLayout; import android.support.design.widget.TextInputLayout;
@ -17,6 +18,7 @@ import android.view.animation.DecelerateInterpolator;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.EditText; import android.widget.EditText;
import android.widget.Spinner; import android.widget.Spinner;
import android.widget.TextView;
import com.afollestad.nocknock.R; import com.afollestad.nocknock.R;
import com.afollestad.nocknock.api.ServerModel; import com.afollestad.nocknock.api.ServerModel;
@ -34,6 +36,8 @@ public class AddSiteActivity extends AppCompatActivity implements View.OnClickLi
private EditText inputUrl; private EditText inputUrl;
private EditText inputInterval; private EditText inputInterval;
private Spinner spinnerInterval; private Spinner spinnerInterval;
private TextView textUrlWarning;
private boolean isClosing; private boolean isClosing;
@Override @Override
@ -44,13 +48,12 @@ public class AddSiteActivity extends AppCompatActivity implements View.OnClickLi
rootLayout = findViewById(R.id.rootView); rootLayout = findViewById(R.id.rootView);
inputName = (EditText) findViewById(R.id.inputName); inputName = (EditText) findViewById(R.id.inputName);
inputUrl = (EditText) findViewById(R.id.inputUrl); inputUrl = (EditText) findViewById(R.id.inputUrl);
textUrlWarning = (TextView) findViewById(R.id.textUrlWarning);
inputInterval = (EditText) findViewById(R.id.checkIntervalInput); inputInterval = (EditText) findViewById(R.id.checkIntervalInput);
spinnerInterval = (Spinner) findViewById(R.id.checkIntervalSpinner); spinnerInterval = (Spinner) findViewById(R.id.checkIntervalSpinner);
toolbar = (Toolbar) findViewById(R.id.toolbar); toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setNavigationOnClickListener(view -> { toolbar.setNavigationOnClickListener(view -> closeActivityWithReveal());
closeActivityWithReveal();
});
if (savedInstanceState == null) { if (savedInstanceState == null) {
rootLayout.setVisibility(View.INVISIBLE); rootLayout.setVisibility(View.INVISIBLE);
@ -70,6 +73,23 @@ public class AddSiteActivity extends AppCompatActivity implements View.OnClickLi
getResources().getStringArray(R.array.interval_options)); getResources().getStringArray(R.array.interval_options));
spinnerInterval.setAdapter(intervalOptionsAdapter); spinnerInterval.setAdapter(intervalOptionsAdapter);
inputUrl.setOnFocusChangeListener((view, hasFocus) -> {
if (!hasFocus) {
final String inputStr = inputUrl.getText().toString().trim();
if (inputStr.isEmpty()) return;
final Uri uri = Uri.parse(inputStr);
if (uri.getScheme() == null) {
inputUrl.setText("http://" + inputStr);
textUrlWarning.setVisibility(View.GONE);
} else if (!"http".equals(uri.getScheme()) && !"https".equals(uri.getScheme())) {
textUrlWarning.setVisibility(View.VISIBLE);
textUrlWarning.setText(R.string.warning_http_url);
} else {
textUrlWarning.setVisibility(View.GONE);
}
}
});
findViewById(R.id.doneBtn).setOnClickListener(this); findViewById(R.id.doneBtn).setOnClickListener(this);
} }
@ -144,6 +164,10 @@ public class AddSiteActivity extends AppCompatActivity implements View.OnClickLi
urlTl.setError(getString(R.string.please_enter_valid_url)); urlTl.setError(getString(R.string.please_enter_valid_url));
isClosing = false; isClosing = false;
return; return;
} else {
final Uri uri = Uri.parse(model.url);
if (uri.getScheme() == null)
model.url = "http://" + model.url;
} }
} }

View file

@ -5,6 +5,7 @@ import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
@ -42,6 +43,7 @@ public class ViewSiteActivity extends AppCompatActivity implements View.OnClickL
private Spinner checkIntervalSpinner; private Spinner checkIntervalSpinner;
private TextView textLastCheckResult; private TextView textLastCheckResult;
private TextView textNextCheck; private TextView textNextCheck;
private TextView textUrlWarning;
private ServerModel mModel; private ServerModel mModel;
@ -70,6 +72,7 @@ public class ViewSiteActivity extends AppCompatActivity implements View.OnClickL
iconStatus = (StatusImageView) findViewById(R.id.iconStatus); iconStatus = (StatusImageView) findViewById(R.id.iconStatus);
inputName = (EditText) findViewById(R.id.inputName); inputName = (EditText) findViewById(R.id.inputName);
inputUrl = (EditText) findViewById(R.id.inputUrl); inputUrl = (EditText) findViewById(R.id.inputUrl);
textUrlWarning = (TextView) findViewById(R.id.textUrlWarning);
inputCheckInterval = (EditText) findViewById(R.id.checkIntervalInput); inputCheckInterval = (EditText) findViewById(R.id.checkIntervalInput);
checkIntervalSpinner = (Spinner) findViewById(R.id.checkIntervalSpinner); checkIntervalSpinner = (Spinner) findViewById(R.id.checkIntervalSpinner);
textLastCheckResult = (TextView) findViewById(R.id.textLastCheckResult); textLastCheckResult = (TextView) findViewById(R.id.textLastCheckResult);
@ -79,6 +82,23 @@ public class ViewSiteActivity extends AppCompatActivity implements View.OnClickL
getResources().getStringArray(R.array.interval_options)); getResources().getStringArray(R.array.interval_options));
checkIntervalSpinner.setAdapter(intervalOptionsAdapter); checkIntervalSpinner.setAdapter(intervalOptionsAdapter);
inputUrl.setOnFocusChangeListener((view, hasFocus) -> {
if (!hasFocus) {
final String inputStr = inputUrl.getText().toString().trim();
if (inputStr.isEmpty()) return;
final Uri uri = Uri.parse(inputStr);
if (uri.getScheme() == null) {
inputUrl.setText("http://" + inputStr);
textUrlWarning.setVisibility(View.GONE);
} else if (!"http".equals(uri.getScheme()) && !"https".equals(uri.getScheme())) {
textUrlWarning.setVisibility(View.VISIBLE);
textUrlWarning.setText(R.string.warning_http_url);
} else {
textUrlWarning.setVisibility(View.GONE);
}
}
});
mModel = (ServerModel) getIntent().getSerializableExtra("model"); mModel = (ServerModel) getIntent().getSerializableExtra("model");
update(); update();
@ -197,6 +217,10 @@ public class ViewSiteActivity extends AppCompatActivity implements View.OnClickL
if (!Patterns.WEB_URL.matcher(mModel.url).find()) { if (!Patterns.WEB_URL.matcher(mModel.url).find()) {
inputUrl.setError(getString(R.string.please_enter_valid_url)); inputUrl.setError(getString(R.string.please_enter_valid_url));
return; return;
} else {
final Uri uri = Uri.parse(mModel.url);
if (uri.getScheme() == null)
mModel.url = "http://" + mModel.url;
} }
} }

View file

@ -69,6 +69,16 @@
</android.support.design.widget.TextInputLayout> </android.support.design.widget.TextInputLayout>
<TextView
android:id="@+id/textUrlWarning"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/list_text_spacing"
android:fontFamily="sans-serif-light"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/caption_font_size"
tools:text="Warning: this app checks for server availability with HTTP requests. It's recommended that you use an HTTP URL." />
<TextView <TextView
android:id="@+id/checkIntervalLabel" android:id="@+id/checkIntervalLabel"
android:layout_width="wrap_content" android:layout_width="wrap_content"

View file

@ -75,6 +75,18 @@
android:textSize="@dimen/body_font_size" android:textSize="@dimen/body_font_size"
android:transitionName="site_url" /> android:transitionName="site_url" />
<TextView
android:id="@+id/textUrlWarning"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="4dp"
android:layout_marginStart="4dp"
android:layout_marginTop="@dimen/list_text_spacing"
android:fontFamily="sans-serif-light"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/caption_font_size"
tools:text="Warning: this app checks for server availability with HTTP requests. It's recommended that you use an HTTP URL." />
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
@ -140,7 +152,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/list_text_spacing" android:layout_marginTop="@dimen/list_text_spacing"
android:fontFamily="sans-serif" android:fontFamily="sans-serif"
android:textColor="?android:textColorSecondary" android:textColor="?android:textColorPrimary"
android:textSize="@dimen/medium_text_size" android:textSize="@dimen/medium_text_size"
tools:text="Everything checks out!" /> tools:text="Everything checks out!" />
@ -158,7 +170,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/list_text_spacing" android:layout_marginTop="@dimen/list_text_spacing"
android:fontFamily="sans-serif" android:fontFamily="sans-serif"
android:textColor="?android:textColorSecondary" android:textColor="?android:textColorPrimary"
android:textSize="@dimen/medium_text_size" android:textSize="@dimen/medium_text_size"
tools:text="In 2 hours" /> tools:text="In 2 hours" />

View file

@ -46,6 +46,10 @@
<string name="swipe_refresh_hint">Drag the list down to manually refresh site statuses! Otherwise, they will be updated automatically in the background on chosen intervals.</string> <string name="swipe_refresh_hint">Drag the list down to manually refresh site statuses! Otherwise, they will be updated automatically in the background on chosen intervals.</string>
<string name="understood">Understood!</string> <string name="understood">Understood!</string>
<string name="warning_http_url">
Warning: this app checks for server availability with HTTP requests. It\'s recommended that you use an HTTP URL.
</string>
<string-array name="interval_options"> <string-array name="interval_options">
<item>Minute(s)</item> <item>Minute(s)</item>
<item>Hour(s)</item> <item>Hour(s)</item>