diff --git a/app/src/main/java/com/idormy/sms/forwarder/AboutActivity.java b/app/src/main/java/com/idormy/sms/forwarder/AboutActivity.java index 8edbf8c7..ff6a5b90 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/AboutActivity.java +++ b/app/src/main/java/com/idormy/sms/forwarder/AboutActivity.java @@ -32,7 +32,6 @@ import java.util.Map; import java.util.Set; -@SuppressWarnings("SpellCheckingInspection") public class AboutActivity extends AppCompatActivity { private final String TAG = "AboutActivity"; private Context context; diff --git a/app/src/main/java/com/idormy/sms/forwarder/SenderActivity.java b/app/src/main/java/com/idormy/sms/forwarder/SenderActivity.java index 67b81d44..02117e63 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/SenderActivity.java +++ b/app/src/main/java/com/idormy/sms/forwarder/SenderActivity.java @@ -59,6 +59,7 @@ import com.idormy.sms.forwarder.sender.SenderUtil; import com.idormy.sms.forwarder.sender.SenderWebNotifyMsg; import com.umeng.analytics.MobclickAgent; +import java.net.Proxy; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; @@ -751,7 +752,6 @@ public class SenderActivity extends AppCompatActivity { } //企业微信群机器人 - @SuppressWarnings("SpellCheckingInspection") @SuppressLint("SimpleDateFormat") private void setQYWXGroupRobot(final SenderModel senderModel) { QYWXGroupRobotSettingVo qywxGroupRobotSettingVo = null; @@ -836,7 +836,6 @@ public class SenderActivity extends AppCompatActivity { } //企业微信应用 - @SuppressWarnings("SpellCheckingInspection") @SuppressLint({"SimpleDateFormat", "SetTextI18n"}) private void setQYWXApp(final SenderModel senderModel) { QYWXAppSettingVo QYWXAppSettingVo = null; @@ -975,13 +974,64 @@ public class SenderActivity extends AppCompatActivity { final EditText editTextTelegramName = view1.findViewById(R.id.editTextTelegramName); if (senderModel != null) editTextTelegramName.setText(senderModel.getName()); + final EditText editTextTelegramApiToken = view1.findViewById(R.id.editTextTelegramApiToken); - if (telegramSettingVo != null) - editTextTelegramApiToken.setText(telegramSettingVo.getApiToken()); final EditText editTextTelegramChatId = view1.findViewById(R.id.editTextTelegramChatId); - if (telegramSettingVo != null) + + final RadioGroup radioGroupProxyType = view1.findViewById(R.id.radioGroupProxyType); + final EditText editTextProxyHost = view1.findViewById(R.id.editTextProxyHost); + final EditText editTextProxyPort = view1.findViewById(R.id.editTextProxyPort); + + @SuppressLint("UseSwitchCompatOrMaterialCode") final Switch switchProxyAuthenticator = view1.findViewById(R.id.switchProxyAuthenticator); + final EditText editTextProxyUsername = view1.findViewById(R.id.editTextProxyUsername); + final EditText editTextProxyPassword = view1.findViewById(R.id.editTextProxyPassword); + + final LinearLayout layoutProxyHost = view1.findViewById(R.id.layoutProxyHost); + final LinearLayout layoutProxyPort = view1.findViewById(R.id.layoutProxyPort); + final LinearLayout layoutProxyAuthenticator = view1.findViewById(R.id.layoutProxyAuthenticator); + + switchProxyAuthenticator.setOnCheckedChangeListener((buttonView, isChecked) -> { + Log.d(TAG, "onCheckedChanged:" + isChecked); + layoutProxyAuthenticator.setVisibility(isChecked ? View.VISIBLE : View.GONE); + }); + + radioGroupProxyType.setOnCheckedChangeListener((group, checkedId) -> { + if (group != null && checkedId > 0) { + if (checkedId == R.id.btnProxyNone) { + layoutProxyHost.setVisibility(View.GONE); + layoutProxyPort.setVisibility(View.GONE); + layoutProxyAuthenticator.setVisibility(View.GONE); + } else { + layoutProxyHost.setVisibility(View.VISIBLE); + layoutProxyPort.setVisibility(View.VISIBLE); + layoutProxyAuthenticator.setVisibility(switchProxyAuthenticator.isChecked() ? View.VISIBLE : View.GONE); + } + group.check(checkedId); + } + }); + + if (telegramSettingVo != null) { + editTextTelegramApiToken.setText(telegramSettingVo.getApiToken()); editTextTelegramChatId.setText(telegramSettingVo.getChatId()); + radioGroupProxyType.check(telegramSettingVo.getProxyTypeCheckId()); + layoutProxyAuthenticator.setVisibility(telegramSettingVo.getProxyAuthenticator() ? View.VISIBLE : View.GONE); + + switchProxyAuthenticator.setChecked(telegramSettingVo.getProxyAuthenticator()); + if (Proxy.Type.DIRECT == telegramSettingVo.getProxyType()) { + layoutProxyHost.setVisibility(View.GONE); + layoutProxyPort.setVisibility(View.GONE); + } else { + layoutProxyHost.setVisibility(View.VISIBLE); + layoutProxyPort.setVisibility(View.VISIBLE); + } + editTextProxyHost.setText(telegramSettingVo.getProxyHost()); + editTextProxyPort.setText(telegramSettingVo.getProxyPort()); + + editTextProxyUsername.setText(telegramSettingVo.getProxyUsername()); + editTextProxyPassword.setText(telegramSettingVo.getProxyPassword()); + } + Button buttonTelegramOk = view1.findViewById(R.id.buttonTelegramOk); Button buttonTelegramDel = view1.findViewById(R.id.buttonTelegramDel); Button buttonTelegramTest = view1.findViewById(R.id.buttonTelegramTest); @@ -1001,7 +1051,14 @@ public class SenderActivity extends AppCompatActivity { newSenderModel.setStatus(STATUS_ON); TelegramSettingVo telegramSettingVoNew = new TelegramSettingVo( editTextTelegramApiToken.getText().toString().trim(), - editTextTelegramChatId.getText().toString().trim() + editTextTelegramChatId.getText().toString().trim(), + radioGroupProxyType.getCheckedRadioButtonId(), + editTextProxyHost.getText().toString().trim(), + editTextProxyPort.getText().toString().trim(), + switchProxyAuthenticator.isChecked(), + editTextProxyUsername.getText().toString().trim(), + editTextProxyPassword.getText().toString().trim() + ); newSenderModel.setJsonSetting(JSON.toJSONString(telegramSettingVoNew)); SenderUtil.addSender(newSenderModel); @@ -1013,7 +1070,13 @@ public class SenderActivity extends AppCompatActivity { senderModel.setStatus(STATUS_ON); TelegramSettingVo telegramSettingVoNew = new TelegramSettingVo( editTextTelegramApiToken.getText().toString().trim(), - editTextTelegramChatId.getText().toString().trim() + editTextTelegramChatId.getText().toString().trim(), + radioGroupProxyType.getCheckedRadioButtonId(), + editTextProxyHost.getText().toString().trim(), + editTextProxyPort.getText().toString().trim(), + switchProxyAuthenticator.isChecked(), + editTextProxyUsername.getText().toString().trim(), + editTextProxyPassword.getText().toString().trim() ); senderModel.setJsonSetting(JSON.toJSONString(telegramSettingVoNew)); SenderUtil.updateSender(senderModel); @@ -1037,7 +1100,17 @@ public class SenderActivity extends AppCompatActivity { String chatId = editTextTelegramChatId.getText().toString().trim(); if (!apiToken.isEmpty() && !chatId.isEmpty()) { try { - SenderTelegramMsg.sendMsg(0, handler, apiToken, chatId, getString(R.string.test_phone_num), getString(R.string.test_sms)); + TelegramSettingVo telegramSettingVoNew = new TelegramSettingVo( + apiToken, + chatId, + radioGroupProxyType.getCheckedRadioButtonId(), + editTextProxyHost.getText().toString().trim(), + editTextProxyPort.getText().toString().trim(), + switchProxyAuthenticator.isChecked(), + editTextProxyUsername.getText().toString().trim(), + editTextProxyPassword.getText().toString().trim() + ); + SenderTelegramMsg.sendMsg(0, handler, telegramSettingVoNew, getString(R.string.test_phone_num), getString(R.string.test_sms)); } catch (Exception e) { Toast.makeText(SenderActivity.this, getString(R.string.failed_to_fwd) + e.getMessage(), Toast.LENGTH_LONG).show(); e.printStackTrace(); diff --git a/app/src/main/java/com/idormy/sms/forwarder/model/vo/TelegramSettingVo.java b/app/src/main/java/com/idormy/sms/forwarder/model/vo/TelegramSettingVo.java index 6c3a8c35..b4cf4c69 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/model/vo/TelegramSettingVo.java +++ b/app/src/main/java/com/idormy/sms/forwarder/model/vo/TelegramSettingVo.java @@ -1,6 +1,9 @@ package com.idormy.sms.forwarder.model.vo; +import com.idormy.sms.forwarder.R; + import java.io.Serializable; +import java.net.Proxy; import lombok.Data; @@ -8,6 +11,12 @@ import lombok.Data; public class TelegramSettingVo implements Serializable { private String apiToken; private String chatId; + private Proxy.Type proxyType = Proxy.Type.DIRECT; + private String proxyHost; + private String proxyPort; + private Boolean proxyAuthenticator = false; + private String proxyUsername; + private String proxyPassword; public TelegramSettingVo() { } @@ -15,5 +24,33 @@ public class TelegramSettingVo implements Serializable { public TelegramSettingVo(String apiToken, String chatId) { this.apiToken = apiToken; this.chatId = chatId; + this.proxyType = Proxy.Type.DIRECT; + } + + public TelegramSettingVo(String apiToken, String chatId, int proxyTypeId, String proxyHost, String proxyPort, boolean proxyAuthenticator, String proxyUsername, String proxyPassword) { + this.apiToken = apiToken; + this.chatId = chatId; + if (proxyTypeId == R.id.btnProxyHttp) { + this.proxyType = Proxy.Type.HTTP; + } else if (proxyTypeId == R.id.btnProxySocks) { + this.proxyType = Proxy.Type.SOCKS; + } else { + this.proxyType = Proxy.Type.DIRECT; + } + this.proxyHost = proxyHost; + this.proxyPort = proxyPort; + this.proxyAuthenticator = proxyAuthenticator; + this.proxyUsername = proxyUsername; + this.proxyPassword = proxyPassword; + } + + public int getProxyTypeCheckId() { + if (proxyType == Proxy.Type.HTTP) { + return R.id.btnProxyHttp; + } else if (proxyType == Proxy.Type.SOCKS) { + return R.id.btnProxySocks; + } else { + return R.id.btnProxyNone; + } } } diff --git a/app/src/main/java/com/idormy/sms/forwarder/sender/SendUtil.java b/app/src/main/java/com/idormy/sms/forwarder/sender/SendUtil.java index c79f654d..703491e5 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/sender/SendUtil.java +++ b/app/src/main/java/com/idormy/sms/forwarder/sender/SendUtil.java @@ -225,7 +225,7 @@ public class SendUtil { TelegramSettingVo telegramSettingVo = JSON.parseObject(senderModel.getJsonSetting(), TelegramSettingVo.class); if (telegramSettingVo != null) { try { - SenderTelegramMsg.sendMsg(logId, handError, telegramSettingVo.getApiToken(), telegramSettingVo.getChatId(), smsVo.getMobile(), smsVo.getSmsVoForSend(smsTemplate, regexReplace)); + SenderTelegramMsg.sendMsg(logId, handError, telegramSettingVo, smsVo.getMobile(), smsVo.getSmsVoForSend(smsTemplate, regexReplace)); } catch (Exception e) { LogUtil.updateLog(logId, 0, e.getMessage()); Log.e(TAG, "senderSendMsg: SenderTelegramMsg error " + e.getMessage()); diff --git a/app/src/main/java/com/idormy/sms/forwarder/sender/SenderTelegramMsg.java b/app/src/main/java/com/idormy/sms/forwarder/sender/SenderTelegramMsg.java index 25e7ad85..f3a141e2 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/sender/SenderTelegramMsg.java +++ b/app/src/main/java/com/idormy/sms/forwarder/sender/SenderTelegramMsg.java @@ -1,15 +1,19 @@ package com.idormy.sms.forwarder.sender; import android.os.Handler; +import android.text.TextUtils; import android.util.Log; import androidx.annotation.NonNull; import com.alibaba.fastjson.JSON; +import com.idormy.sms.forwarder.model.vo.TelegramSettingVo; import com.idormy.sms.forwarder.utils.LogUtil; import com.idormy.sms.forwarder.utils.SettingUtil; import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.Proxy; import java.util.HashMap; import java.util.Map; import java.util.Objects; @@ -17,8 +21,11 @@ import java.util.concurrent.TimeUnit; import io.reactivex.rxjava3.core.Observable; import io.reactivex.rxjava3.core.ObservableEmitter; +import okhttp3.Authenticator; import okhttp3.Call; import okhttp3.Callback; +import okhttp3.ConnectionPool; +import okhttp3.Credentials; import okhttp3.MediaType; import okhttp3.OkHttpClient; import okhttp3.Request; @@ -30,9 +37,11 @@ public class SenderTelegramMsg extends SenderBaseMsg { static final String TAG = "SenderTelegramMsg"; - public static void sendMsg(final long logId, final Handler handError, String apiToken, String chatId, String from, String text) throws Exception { - Log.i(TAG, "sendMsg apiToken:" + apiToken + " chatId:" + chatId + " text:" + text); + public static void sendMsg(final long logId, final Handler handError, TelegramSettingVo telegramSettingVo, String from, String text) throws Exception { + Log.i(TAG, "sendMsg telegramSettingVo:" + telegramSettingVo.toString() + " text:" + text); + String apiToken = telegramSettingVo.getApiToken(); + String chatId = telegramSettingVo.getChatId(); if (apiToken == null || apiToken.isEmpty()) { return; } @@ -54,42 +63,87 @@ public class SenderTelegramMsg extends SenderBaseMsg { final String requestMsg = JSON.toJSONString(bodyMap); Log.i(TAG, "requestMsg:" + requestMsg); + //代理相关 + final Proxy.Type proxyType = telegramSettingVo.getProxyType(); + final String proxyHost = telegramSettingVo.getProxyHost(); + final String proxyPort = telegramSettingVo.getProxyPort(); + final Boolean needProxyAuthenticator = telegramSettingVo.getProxyAuthenticator(); + final String proxyUsername = telegramSettingVo.getProxyUsername(); + final String proxyPassword = telegramSettingVo.getProxyPassword(); + Observable .create((ObservableEmitter emitter) -> { Toast(handError, TAG, "开始请求接口..."); - OkHttpClient client = new OkHttpClient(); - RequestBody requestBody = RequestBody.create(MediaType.parse("application/json;charset=utf-8"), requestMsg); + try { + Proxy proxy = null; + Authenticator proxyAuthenticator = null; - final Request request = new Request.Builder() - .url(requestUrl) - .addHeader("Content-Type", "application/json; charset=utf-8") - .post(requestBody) - .build(); - Call call = client.newCall(request); - call.enqueue(new Callback() { - @Override - public void onFailure(@NonNull Call call, @NonNull final IOException e) { - LogUtil.updateLog(logId, 0, e.getMessage()); - Toast(handError, TAG, "发送失败:" + e.getMessage()); - emitter.onError(new RuntimeException("请求接口异常...")); - } + if ((proxyType == Proxy.Type.HTTP || proxyType == Proxy.Type.SOCKS) && !TextUtils.isEmpty(proxyHost) && !TextUtils.isEmpty(proxyPort)) { + proxy = new Proxy(proxyType, new InetSocketAddress(proxyHost, Integer.parseInt(proxyPort))); - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException { - final String responseStr = Objects.requireNonNull(response.body()).string(); - Log.d(TAG, "Response:" + response.code() + "," + responseStr); - Toast(handError, TAG, "发送状态:" + responseStr); - - //TODO:粗略解析是否发送成功 - if (responseStr.contains("\"ok\":true")) { - LogUtil.updateLog(logId, 2, responseStr); - } else { - LogUtil.updateLog(logId, 0, responseStr); + if (needProxyAuthenticator && (!TextUtils.isEmpty(proxyUsername) || !TextUtils.isEmpty(proxyPassword))) { + proxyAuthenticator = (route, response) -> { + String credential = Credentials.basic("jesse", "password1"); + return response.request().newBuilder() + .header("Authorization", credential) + .build(); + }; } } - }); + OkHttpClient client; + if (proxy != null && proxyAuthenticator != null) { + client = new OkHttpClient().newBuilder().proxy(proxy).proxyAuthenticator(proxyAuthenticator) + .connectTimeout(120, TimeUnit.SECONDS).readTimeout(120, TimeUnit.SECONDS) + .connectionPool(new ConnectionPool(5, 1, TimeUnit.SECONDS)).build(); + } else if (proxy != null) { + client = new OkHttpClient().newBuilder().proxy(proxy) + .connectTimeout(120, TimeUnit.SECONDS).readTimeout(120, TimeUnit.SECONDS) + .connectionPool(new ConnectionPool(5, 1, TimeUnit.SECONDS)).build(); + } else { + client = new OkHttpClient().newBuilder() + .connectTimeout(120, TimeUnit.SECONDS).readTimeout(120, TimeUnit.SECONDS) + .connectionPool(new ConnectionPool(5, 1, TimeUnit.SECONDS)).build(); + } + + RequestBody requestBody = RequestBody.create(MediaType.parse("application/json;charset=utf-8"), requestMsg); + + final Request request = new Request.Builder() + .url(requestUrl) + .addHeader("Content-Type", "application/json; charset=utf-8") + .post(requestBody) + .build(); + + client.newCall(request).enqueue(new Callback() { + @Override + public void onFailure(@NonNull Call call, @NonNull final IOException e) { + LogUtil.updateLog(logId, 0, e.getMessage()); + Toast(handError, TAG, "发送失败:" + e.getMessage()); + emitter.onError(new RuntimeException("请求接口异常...")); + } + + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException { + final String responseStr = Objects.requireNonNull(response.body()).string(); + Log.d(TAG, "Response:" + response.code() + "," + responseStr); + Toast(handError, TAG, "发送状态:" + responseStr); + + //TODO:粗略解析是否发送成功 + if (responseStr.contains("\"ok\":true")) { + LogUtil.updateLog(logId, 2, responseStr); + } else { + LogUtil.updateLog(logId, 0, responseStr); + } + } + }); + + } catch (Exception e) { + LogUtil.updateLog(logId, 0, e.getMessage()); + Log.e(TAG, e.getMessage(), e); + Toast(handError, TAG, "发送失败:" + e.getMessage()); + emitter.onError(new RuntimeException("请求接口异常...")); + } }).retryWhen((Observable errorObservable) -> errorObservable .zipWith(Observable.just( SettingUtil.getRetryDelayTime(1), diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/LogUtil.java b/app/src/main/java/com/idormy/sms/forwarder/utils/LogUtil.java index 19e7d1a5..0929838d 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/utils/LogUtil.java +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/LogUtil.java @@ -89,7 +89,7 @@ public class LogUtil { public static void updateLog(Long id, int forward_status, String forward_response) { if (id == null || id <= 0) return; - String sql = new StringBuilder().append("UPDATE ").append(LogTable.LogEntry.TABLE_NAME) + @SuppressWarnings("StringBufferReplaceableByString") String sql = new StringBuilder().append("UPDATE ").append(LogTable.LogEntry.TABLE_NAME) .append(" SET ").append(LogTable.LogEntry.COLUMN_NAME_FORWARD_STATUS).append(" = ? , ") .append(LogTable.LogEntry.COLUMN_NAME_FORWARD_RESPONSE) .append(" = CASE WHEN ").append(LogTable.LogEntry.COLUMN_NAME_FORWARD_STATUS).append(" = 1 THEN ? ELSE ") diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/PhoneUtils.java b/app/src/main/java/com/idormy/sms/forwarder/utils/PhoneUtils.java index eb2738d2..93140862 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/utils/PhoneUtils.java +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/PhoneUtils.java @@ -577,7 +577,6 @@ public class PhoneUtils { /** * SIM 卡信息 */ - @SuppressWarnings("SpellCheckingInspection") public static class SimInfo { /** * 运营商信息:中国移动 中国联通 中国电信 diff --git a/app/src/main/res/layout/alert_dialog_setview_email.xml b/app/src/main/res/layout/alert_dialog_setview_email.xml index dc0bbf6a..18e8bf65 100644 --- a/app/src/main/res/layout/alert_dialog_setview_email.xml +++ b/app/src/main/res/layout/alert_dialog_setview_email.xml @@ -29,6 +29,7 @@ android:autofillHints="" android:ems="11" android:inputType="text" + android:maxLines="1" android:text="" tools:ignore="LabelFor,TextFields" /> @@ -63,6 +64,7 @@ android:autofillHints="" android:ems="14" android:inputType="textEmailAddress" + android:maxLines="1" android:text="" tools:ignore="LabelFor" /> @@ -87,6 +89,7 @@ android:autofillHints="" android:ems="14" android:inputType="textPassword" + android:maxLines="1" android:text="" tools:ignore="LabelFor,TextFields" /> @@ -111,6 +114,7 @@ android:autofillHints="" android:ems="14" android:inputType="text" + android:maxLines="1" android:text="" tools:ignore="LabelFor,TextFields" /> @@ -184,6 +188,7 @@ android:autofillHints="" android:ems="14" android:inputType="text" + android:maxLines="1" android:text="" tools:ignore="LabelFor,TextFields" /> @@ -207,7 +212,8 @@ android:layout_marginStart="3dp" android:autofillHints="" android:ems="5" - android:inputType="text" + android:inputType="number" + android:maxLines="1" android:text="" tools:ignore="LabelFor,TextFields" /> @@ -254,6 +260,7 @@ android:autofillHints="" android:ems="14" android:inputType="textEmailAddress" + android:maxLines="1" android:text="" tools:ignore="LabelFor" /> diff --git a/app/src/main/res/layout/alert_dialog_setview_telegram.xml b/app/src/main/res/layout/alert_dialog_setview_telegram.xml index d5a72ed3..2269642b 100644 --- a/app/src/main/res/layout/alert_dialog_setview_telegram.xml +++ b/app/src/main/res/layout/alert_dialog_setview_telegram.xml @@ -19,7 +19,8 @@ + android:text="@string/set_name" + android:textStyle="bold" /> + android:text="@string/TelegramApiToken" + android:textStyle="bold" /> + android:text="@string/TelegramChatId" + android:textStyle="bold" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 Monitor battery status changes Notify when charging status changes (charging/discharging/uncharged/fully charged) + Proxy Settings + None + HTTP + SOCKS + Hostname + Port + Proxy Authenticator + Username + Password diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e5507f64..e0eb5532 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -253,4 +253,13 @@ 0 监听电池状态变化 充电状态改变(充电中/放电中/未充电/已充满)时发出通知 + 代理设置 + 无代理 + HTTP + SOCKS + 主机名 + 端口号 + 代理身份验证 + 用户 + 密码