From 3f7bb163ac425864943f6e421c2819ee01b2945b Mon Sep 17 00:00:00 2001 From: Konstantin Bogomolov Date: Tue, 14 Feb 2023 02:53:35 +0700 Subject: [PATCH] V2.2.1 sdk 14 (#30) * Min sdk 14 * Skip ssl check if needed * Fix few bugs (service start when no configs, slot index message) * Add autostart on phone start * Make dialog scrollable --- app/build.gradle | 10 +- .../incomingsmsgateway/MainActivityTest.java | 10 + .../incomingsmsgateway/SmsReceiverTest.java | 12 +- .../incomingsmsgateway/WebhookCallerTest.java | 16 +- app/src/main/AndroidManifest.xml | 10 + .../BootCompletedReceiver.java | 20 ++ .../incomingsmsgateway/ForwardingConfig.java | 16 ++ .../incomingsmsgateway/ListAdapter.java | 23 ++ .../incomingsmsgateway/MainActivity.java | 177 ++++++------- .../incomingsmsgateway/SmsReceiver.java | 15 +- .../SmsReceiverService.java | 7 +- .../WebHookWorkRequest.java | 28 ++- app/src/main/res/layout/dialog_add.xml | 235 ++++++++++-------- app/src/main/res/layout/list_item.xml | 1 - app/src/main/res/values/strings.xml | 1 + 15 files changed, 354 insertions(+), 227 deletions(-) create mode 100644 app/src/main/java/tech/bogomolov/incomingsmsgateway/BootCompletedReceiver.java diff --git a/app/build.gradle b/app/build.gradle index bbbcb34..12139f1 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,15 +1,15 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 31 + compileSdkVersion 33 buildToolsVersion "30.0.3" defaultConfig { applicationId "tech.bogomolov.incomingsmsgateway" - minSdkVersion 23 - targetSdkVersion 31 - versionCode 8 - versionName "2.1.1" + minSdkVersion 14 + targetSdkVersion 33 + versionCode 9 + versionName "2.2.1" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } diff --git a/app/src/androidTest/java/tech/bogomolov/incomingsmsgateway/MainActivityTest.java b/app/src/androidTest/java/tech/bogomolov/incomingsmsgateway/MainActivityTest.java index 2331dff..b4e52ea 100644 --- a/app/src/androidTest/java/tech/bogomolov/incomingsmsgateway/MainActivityTest.java +++ b/app/src/androidTest/java/tech/bogomolov/incomingsmsgateway/MainActivityTest.java @@ -3,12 +3,15 @@ import android.content.Context; import android.content.SharedPreferences; +import androidx.lifecycle.Lifecycle; +import androidx.test.core.app.ActivityScenario; import androidx.test.core.app.ApplicationProvider; import androidx.test.espresso.ViewInteraction; import androidx.test.ext.junit.rules.ActivityScenarioRule; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.platform.app.InstrumentationRegistry; +import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -41,6 +44,13 @@ public void clearSharedPrefs() { editor.commit(); } + @After + public void recreateActivity() { + ActivityScenario scenario = activityRule.getScenario(); + scenario.moveToState(Lifecycle.State.RESUMED); + scenario.recreate(); + } + @Test public void testAddDialogOpen() { onView(withId(R.id.btn_add)).perform(click()); diff --git a/app/src/androidTest/java/tech/bogomolov/incomingsmsgateway/SmsReceiverTest.java b/app/src/androidTest/java/tech/bogomolov/incomingsmsgateway/SmsReceiverTest.java index 6abd4ce..33c8d33 100644 --- a/app/src/androidTest/java/tech/bogomolov/incomingsmsgateway/SmsReceiverTest.java +++ b/app/src/androidTest/java/tech/bogomolov/incomingsmsgateway/SmsReceiverTest.java @@ -31,7 +31,7 @@ public void testEmptyConfig() { receiver.onReceive(appContext, this.getIntent()); Mockito.verify(receiver, Mockito.times(0)) - .callWebHook(Mockito.anyString(), Mockito.anyString(), Mockito.anyString()); + .callWebHook(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyBoolean()); } @Test @@ -41,7 +41,7 @@ public void testSmsPassedToWebhookByWildcard() { receiver.onReceive(appContext, this.getIntent()); Mockito.verify(receiver, Mockito.times(1)) - .callWebHook(Mockito.anyString(), Mockito.anyString(), Mockito.anyString()); + .callWebHook(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyBoolean()); } @Test @@ -51,7 +51,7 @@ public void testSmsPassedToWebhookByNumber() { receiver.onReceive(appContext, this.getIntent()); Mockito.verify(receiver, Mockito.times(1)) - .callWebHook(Mockito.anyString(), Mockito.anyString(), Mockito.anyString()); + .callWebHook(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyBoolean()); } @Test @@ -61,7 +61,7 @@ public void testSmsNotPassedToWebhook() { receiver.onReceive(appContext, this.getIntent()); Mockito.verify(receiver, Mockito.times(0)) - .callWebHook(Mockito.anyString(), Mockito.anyString(), Mockito.anyString()); + .callWebHook(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyBoolean()); } @Test @@ -73,7 +73,7 @@ public void testMultiplePdus() { Mockito.verify(receiver, Mockito.times(1)) .callWebHook(Mockito.anyString(), Mockito.contains("\"text\":\"TestTest\""), - Mockito.anyString()); + Mockito.anyString(), Mockito.anyBoolean()); } private void setPhoneConfig(Context context, String phone) { @@ -107,7 +107,7 @@ private SmsReceiver getSmsReceiver() { Mockito.doCallRealMethod() .when(receiver).onReceive(Mockito.any(Context.class), Mockito.any(Intent.class)); Mockito.doNothing().when(receiver) - .callWebHook(Mockito.anyString(), Mockito.anyString(), Mockito.anyString()); + .callWebHook(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyBoolean()); return receiver; } diff --git a/app/src/androidTest/java/tech/bogomolov/incomingsmsgateway/WebhookCallerTest.java b/app/src/androidTest/java/tech/bogomolov/incomingsmsgateway/WebhookCallerTest.java index bca53f4..4a1a34d 100644 --- a/app/src/androidTest/java/tech/bogomolov/incomingsmsgateway/WebhookCallerTest.java +++ b/app/src/androidTest/java/tech/bogomolov/incomingsmsgateway/WebhookCallerTest.java @@ -38,27 +38,35 @@ public void setup() { @Test public void testHttpsSuccess() throws Exception { - WorkInfo workInfo = this.getWorkInfo("https://example.com", "test", "{}"); + WorkInfo workInfo = this.getWorkInfo("https://example.com", "test", "{}", false); assertThat(workInfo.getState(), is(WorkInfo.State.SUCCEEDED)); } @Test public void testHttpSuccess() throws Exception { - WorkInfo workInfo = this.getWorkInfo("http://example.com", "test", "{}"); + WorkInfo workInfo = this.getWorkInfo("http://example.com", "test", "{}", false); assertThat(workInfo.getState(), is(WorkInfo.State.SUCCEEDED)); } @Test public void testError() throws Exception { - WorkInfo workInfo = this.getWorkInfo("not a url", "test", "{}"); + WorkInfo workInfo = this.getWorkInfo("not a url", "test", "{}", false); assertThat(workInfo.getState(), is(WorkInfo.State.FAILED)); } - private WorkInfo getWorkInfo(String url, String text, String headers) throws Exception { + @Test + public void testSelfSignedCert() throws Exception { + WorkInfo workInfo = this.getWorkInfo( + "https://self-signed.badssl.com/", "test", "{\"User-Agent\":\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36\"}", true); + assertThat(workInfo.getState(), is(WorkInfo.State.SUCCEEDED)); + } + + private WorkInfo getWorkInfo(String url, String text, String headers, boolean ignoreSsl) throws Exception { Data input = new Data.Builder() .put(WebHookWorkRequest.DATA_URL, url) .put(WebHookWorkRequest.DATA_TEXT, text) .put(WebHookWorkRequest.DATA_HEADERS, headers) + .put(WebHookWorkRequest.DATA_IGNORE_SSL, ignoreSsl) .build(); OneTimeWorkRequest request = new OneTimeWorkRequest.Builder(WebHookWorkRequest.class) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 221087f..611c60e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -6,6 +6,7 @@ + + + + + + + = Build.VERSION_CODES.O) { + context.startForegroundService(intent); + } else { + context.startService(intent); + } + } +} diff --git a/app/src/main/java/tech/bogomolov/incomingsmsgateway/ForwardingConfig.java b/app/src/main/java/tech/bogomolov/incomingsmsgateway/ForwardingConfig.java index 756dead..67a92e0 100644 --- a/app/src/main/java/tech/bogomolov/incomingsmsgateway/ForwardingConfig.java +++ b/app/src/main/java/tech/bogomolov/incomingsmsgateway/ForwardingConfig.java @@ -16,11 +16,13 @@ public class ForwardingConfig { private static final String KEY_URL = "url"; private static final String KEY_TEMPLATE = "template"; private static final String KEY_HEADERS = "headers"; + private static final String KEY_IGNORE_SSL = "ignore_ssl"; private String sender; private String url; private String template; private String headers; + private boolean ignoreSsl = false; public ForwardingConfig(Context context) { this.context = context; @@ -58,12 +60,21 @@ public void setHeaders(String headers) { this.headers = headers; } + public boolean getIgnoreSsl() { + return this.ignoreSsl; + } + + public void setIgnoreSsl(boolean ignoreSsl) { + this.ignoreSsl = ignoreSsl; + } + public void save() { try { JSONObject json = new JSONObject(); json.put(KEY_URL, this.url); json.put(KEY_TEMPLATE, this.template); json.put(KEY_HEADERS, this.headers); + json.put(KEY_IGNORE_SSL, this.ignoreSsl); SharedPreferences.Editor editor = getEditor(context); editor.putString(this.sender, json.toString()); @@ -100,6 +111,11 @@ public static ArrayList getAll(Context context) { config.setUrl(json.getString(KEY_URL)); config.setTemplate(json.getString(KEY_TEMPLATE)); config.setHeaders(json.getString(KEY_HEADERS)); + + try { + config.setIgnoreSsl(json.getBoolean(KEY_IGNORE_SSL)); + } catch (JSONException ignored) { + } } catch (JSONException e) { Log.e("ForwardingConfig", e.getMessage()); } diff --git a/app/src/main/java/tech/bogomolov/incomingsmsgateway/ListAdapter.java b/app/src/main/java/tech/bogomolov/incomingsmsgateway/ListAdapter.java index c5b1aed..8ed23eb 100644 --- a/app/src/main/java/tech/bogomolov/incomingsmsgateway/ListAdapter.java +++ b/app/src/main/java/tech/bogomolov/incomingsmsgateway/ListAdapter.java @@ -1,5 +1,6 @@ package tech.bogomolov.incomingsmsgateway; +import android.app.AlertDialog; import android.content.Context; import android.view.LayoutInflater; import android.view.View; @@ -53,7 +54,29 @@ public View getView(int position, View convertView, ViewGroup parent) { View deleteButton = row.findViewById(R.id.delete_button); deleteButton.setTag(R.id.delete_button, position); + deleteButton.setOnClickListener(this::onDeleteClick); return row; } + + public void onDeleteClick(View view) { + ListAdapter listAdapter = this; + final int position = (int) view.getTag(R.id.delete_button); + final ForwardingConfig config = listAdapter.getItem(position); + + AlertDialog.Builder builder = new AlertDialog.Builder(view.getContext()); + builder.setTitle(R.string.delete_record); + String asterisk = context.getString(R.string.asterisk); + String any = context.getString(R.string.any); + String message = context.getString(R.string.confirm_delete); + message = String.format(message, (config.getSender().equals(asterisk) ? any : config.getSender())); + builder.setMessage(message); + + builder.setPositiveButton(R.string.btn_delete, (dialog, id) -> { + listAdapter.remove(config); + config.remove(); + }); + builder.setNegativeButton(R.string.btn_cancel, null); + builder.show(); + } } diff --git a/app/src/main/java/tech/bogomolov/incomingsmsgateway/MainActivity.java b/app/src/main/java/tech/bogomolov/incomingsmsgateway/MainActivity.java index 64299ae..0da3de3 100644 --- a/app/src/main/java/tech/bogomolov/incomingsmsgateway/MainActivity.java +++ b/app/src/main/java/tech/bogomolov/incomingsmsgateway/MainActivity.java @@ -3,13 +3,14 @@ import android.Manifest; import android.app.AlertDialog; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.os.Build; import android.os.Bundle; import android.text.TextUtils; import android.view.View; +import android.view.WindowManager; +import android.widget.CheckBox; import android.widget.EditText; import android.widget.ListView; import android.widget.TextView; @@ -65,31 +66,6 @@ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permis return; } - - - } - - public void onDeleteClick(View view) { - final int position = (int) view.getTag(R.id.delete_button); - final ForwardingConfig config = listAdapter.getItem(position); - - AlertDialog.Builder builder = new AlertDialog.Builder(context); - builder.setTitle(R.string.delete_record); - String asterisk = context.getString(R.string.asterisk); - String any = context.getString(R.string.any); - String message = context.getString(R.string.confirm_delete); - message = String.format(message, (config.getSender().equals(asterisk) ? any : config.getSender())); - builder.setMessage(message); - - builder.setPositiveButton(R.string.btn_delete, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int id) { - listAdapter.remove(config); - config.remove(); - } - }); - builder.setNegativeButton(R.string.btn_cancel, null); - builder.show(); } private void showList() { @@ -100,15 +76,13 @@ private void showList() { ArrayList configs = ForwardingConfig.getAll(context); - if (configs.size() > 0) { - Context context = getApplicationContext(); - Intent intent = new Intent(this, SmsReceiverService.class); + Context appContext = getApplicationContext(); + Intent intent = new Intent(this, SmsReceiverService.class); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - context.startForegroundService(intent); - } else { - context.startService(intent); - } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + appContext.startForegroundService(intent); + } else { + appContext.startService(intent); } listAdapter = new ListAdapter(configs, context); @@ -125,74 +99,73 @@ private void showInfo(String text) { } private View.OnClickListener showAddDialog() { - return new View.OnClickListener() { - @Override - public void onClick(View v) { - AlertDialog.Builder builder = new AlertDialog.Builder(context); - View view = getLayoutInflater().inflate(R.layout.dialog_add, null); - final EditText senderInput = view.findViewById(R.id.input_phone); - final EditText urlInput = view.findViewById(R.id.input_url); - final EditText templateInput = view.findViewById(R.id.input_json_template); - final EditText headersInput = view.findViewById(R.id.input_json_headers); - - templateInput.setText(ForwardingConfig.getDefaultJsonTemplate()); - headersInput.setText(ForwardingConfig.getDefaultJsonHeaders()); - - builder.setView(view); - builder.setPositiveButton(R.string.btn_add, null); - builder.setNegativeButton(R.string.btn_cancel, null); - final AlertDialog dialog = builder.show(); - dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - String sender = senderInput.getText().toString(); - if (TextUtils.isEmpty(sender)) { - senderInput.setError(getString(R.string.error_empty_sender)); - return; - } - - String url = urlInput.getText().toString(); - if (TextUtils.isEmpty(url)) { - urlInput.setError(getString(R.string.error_empty_url)); - return; - } - - try { - new URL(url); - } catch (MalformedURLException e) { - urlInput.setError(getString(R.string.error_wrong_url)); - return; - } - - String template = templateInput.getText().toString(); - try { - JSONObject jsonObject = new JSONObject(template); - } catch (JSONException e) { - templateInput.setError(getString(R.string.error_wrong_json)); - return; - } - - String headers = headersInput.getText().toString(); - try { - JSONObject jsonObject = new JSONObject(headers); - } catch (JSONException e) { - headersInput.setError(getString(R.string.error_wrong_json)); - return; - } - - ForwardingConfig config = new ForwardingConfig(context); - config.setSender(sender); - config.setUrl(url); - config.setTemplate(template); - config.setHeaders(headers); - config.save(); - - listAdapter.add(config); - - dialog.dismiss(); - } - }); - } + return v -> { + AlertDialog.Builder builder = new AlertDialog.Builder(context); + View view = getLayoutInflater().inflate(R.layout.dialog_add, null); + final EditText senderInput = view.findViewById(R.id.input_phone); + final EditText urlInput = view.findViewById(R.id.input_url); + final EditText templateInput = view.findViewById(R.id.input_json_template); + final EditText headersInput = view.findViewById(R.id.input_json_headers); + final CheckBox ignoreSslCheckbox = view.findViewById(R.id.input_ignore_ssl); + + templateInput.setText(ForwardingConfig.getDefaultJsonTemplate()); + headersInput.setText(ForwardingConfig.getDefaultJsonHeaders()); + + builder.setView(view); + builder.setPositiveButton(R.string.btn_add, null); + builder.setNegativeButton(R.string.btn_cancel, null); + final AlertDialog dialog = builder.show(); + dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); + dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(view1 -> { + String sender = senderInput.getText().toString(); + if (TextUtils.isEmpty(sender)) { + senderInput.setError(getString(R.string.error_empty_sender)); + return; + } + + String url = urlInput.getText().toString(); + if (TextUtils.isEmpty(url)) { + urlInput.setError(getString(R.string.error_empty_url)); + return; + } + + try { + new URL(url); + } catch (MalformedURLException e) { + urlInput.setError(getString(R.string.error_wrong_url)); + return; + } + + String template = templateInput.getText().toString(); + try { + new JSONObject(template); + } catch (JSONException e) { + templateInput.setError(getString(R.string.error_wrong_json)); + return; + } + + String headers = headersInput.getText().toString(); + try { + new JSONObject(headers); + } catch (JSONException e) { + headersInput.setError(getString(R.string.error_wrong_json)); + return; + } + + boolean ignoreSsl = ignoreSslCheckbox.isChecked(); + + ForwardingConfig config = new ForwardingConfig(context); + config.setSender(sender); + config.setUrl(url); + config.setTemplate(template); + config.setHeaders(headers); + config.setIgnoreSsl(ignoreSsl); + config.save(); + + listAdapter.add(config); + + dialog.dismiss(); + }); }; } } diff --git a/app/src/main/java/tech/bogomolov/incomingsmsgateway/SmsReceiver.java b/app/src/main/java/tech/bogomolov/incomingsmsgateway/SmsReceiver.java index 54f306a..04d45d1 100644 --- a/app/src/main/java/tech/bogomolov/incomingsmsgateway/SmsReceiver.java +++ b/app/src/main/java/tech/bogomolov/incomingsmsgateway/SmsReceiver.java @@ -14,8 +14,6 @@ import androidx.work.WorkManager; import androidx.work.WorkRequest; -import org.json.JSONObject; - import java.util.ArrayList; import java.util.Set; import java.util.concurrent.TimeUnit; @@ -70,10 +68,15 @@ public void onReceive(Context context, Intent intent) { .replaceAll("%receivedStamp%", String.valueOf(System.currentTimeMillis())) .replaceAll("%sim%", this.detectSim(bundle)); - this.callWebHook(matchedConfig.getUrl(), messageContent, matchedConfig.getHeaders()); + this.callWebHook( + matchedConfig.getUrl(), + messageContent, + matchedConfig.getHeaders(), + matchedConfig.getIgnoreSsl() + ); } - protected void callWebHook(String url, String message, String headers) { + protected void callWebHook(String url, String message, String headers, boolean ignoreSsl) { Constraints constraints = new Constraints.Builder() .setRequiredNetworkType(NetworkType.CONNECTED) @@ -83,6 +86,7 @@ protected void callWebHook(String url, String message, String headers) { .putString(WebHookWorkRequest.DATA_URL, url) .putString(WebHookWorkRequest.DATA_TEXT, message) .putString(WebHookWorkRequest.DATA_HEADERS, headers) + .putBoolean(WebHookWorkRequest.DATA_IGNORE_SSL, ignoreSsl) .build(); WorkRequest webhookWorkRequest = @@ -131,6 +135,9 @@ private String detectSim(Bundle bundle) { case "slotIdx": slotId = bundle.getInt("slotIdx", -1); break; + case "android.telephony.extra.SLOT_INDEX": + slotId = bundle.getInt("android.telephony.extra.SLOT_INDEX", -1); + break; default: if (key.toLowerCase().contains("slot") | key.toLowerCase().contains("sim")) { String value = bundle.getString(key, "-1"); diff --git a/app/src/main/java/tech/bogomolov/incomingsmsgateway/SmsReceiverService.java b/app/src/main/java/tech/bogomolov/incomingsmsgateway/SmsReceiverService.java index 47555b0..3c14346 100644 --- a/app/src/main/java/tech/bogomolov/incomingsmsgateway/SmsReceiverService.java +++ b/app/src/main/java/tech/bogomolov/incomingsmsgateway/SmsReceiverService.java @@ -9,6 +9,7 @@ import android.content.IntentFilter; import android.os.Build; import android.os.IBinder; +import android.provider.Telephony; import androidx.annotation.Nullable; @@ -27,7 +28,11 @@ public void onCreate() { super.onCreate(); IntentFilter filter = new IntentFilter(); - filter.addAction("android.provider.Telephony.SMS_RECEIVED"); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + filter.addAction(Telephony.Sms.Intents.SMS_RECEIVED_ACTION); + } else { + filter.addAction("android.provider.Telephony.SMS_RECEIVED"); + } registerReceiver(receiver, filter); diff --git a/app/src/main/java/tech/bogomolov/incomingsmsgateway/WebHookWorkRequest.java b/app/src/main/java/tech/bogomolov/incomingsmsgateway/WebHookWorkRequest.java index df32860..187396a 100644 --- a/app/src/main/java/tech/bogomolov/incomingsmsgateway/WebHookWorkRequest.java +++ b/app/src/main/java/tech/bogomolov/incomingsmsgateway/WebHookWorkRequest.java @@ -1,12 +1,15 @@ package tech.bogomolov.incomingsmsgateway; +import android.annotation.SuppressLint; import android.content.Context; +import android.net.SSLCertificateSocketFactory; import android.util.Log; import androidx.annotation.NonNull; import androidx.work.Worker; import androidx.work.WorkerParameters; +import org.apache.http.conn.ssl.AllowAllHostnameVerifier; import org.json.JSONObject; import java.io.BufferedInputStream; @@ -20,12 +23,14 @@ import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.Iterator; +import javax.net.ssl.HttpsURLConnection; public class WebHookWorkRequest extends Worker { public final static String DATA_URL = "URL"; public final static String DATA_TEXT = "TEXT"; public final static String DATA_HEADERS = "HEADERS"; + public final static String DATA_IGNORE_SSL = "IGNORE_SSL"; public static final int MAX_ATTEMPT = 10; public static final String RESULT_SUCCESS = "success"; @@ -48,8 +53,9 @@ public Result doWork() { String url = getInputData().getString(DATA_URL); String text = getInputData().getString(DATA_TEXT); String headers = getInputData().getString(DATA_HEADERS); + boolean ignoreSsl = getInputData().getBoolean(DATA_IGNORE_SSL, false); - String result = this.makeRequest(url, text, headers); + String result = this.makeRequest(url, text, headers, ignoreSsl); if (result.equals(RESULT_RETRY)) { return Result.retry(); @@ -62,13 +68,22 @@ public Result doWork() { return Result.success(); } - private String makeRequest(String urlString, String text, String headers) { + @SuppressLint({"SSLCertificateSocketFactoryGetInsecure", "AllowAllHostnameVerifier"}) + private String makeRequest(String urlString, String text, String headers, boolean ignoreSsl) { String result = RESULT_SUCCESS; + HttpURLConnection urlConnection = null; try { URL url = new URL(urlString); urlConnection = (HttpURLConnection) url.openConnection(); + + if (urlConnection instanceof HttpsURLConnection && ignoreSsl) { + ((HttpsURLConnection) urlConnection).setSSLSocketFactory( + SSLCertificateSocketFactory.getInsecure(0, null)); + ((HttpsURLConnection) urlConnection).setHostnameVerifier(new AllowAllHostnameVerifier()); + } + urlConnection.setDoOutput(true); urlConnection.setChunkedStreamingMode(0); @@ -87,7 +102,14 @@ private String makeRequest(String urlString, String text, String headers) { } OutputStream out = new BufferedOutputStream(urlConnection.getOutputStream()); - BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8)); + + BufferedWriter writer; + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) { + writer = new BufferedWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8)); + } else { + writer = new BufferedWriter(new OutputStreamWriter(out)); + } + writer.write(text); writer.flush(); writer.close(); diff --git a/app/src/main/res/layout/dialog_add.xml b/app/src/main/res/layout/dialog_add.xml index 47014c0..2f42ead 100644 --- a/app/src/main/res/layout/dialog_add.xml +++ b/app/src/main/res/layout/dialog_add.xml @@ -1,113 +1,146 @@ - + - + android:orientation="vertical" + android:scrollbars="vertical"> - + - + - + - + - + - + - + - + - + + + + + + + + + - \ No newline at end of file + + + \ No newline at end of file diff --git a/app/src/main/res/layout/list_item.xml b/app/src/main/res/layout/list_item.xml index e643457..b7a0728 100644 --- a/app/src/main/res/layout/list_item.xml +++ b/app/src/main/res/layout/list_item.xml @@ -80,7 +80,6 @@